summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG23
-rw-r--r--CONTRIBUTING.md45
-rw-r--r--Gemfile24
-rw-r--r--Gemfile.lock187
-rw-r--r--README.md16
-rw-r--r--VERSION2
-rw-r--r--app/assets/images/monokai.pngbin0 -> 6651 bytes
-rw-r--r--app/assets/javascripts/admin.js.coffee41
-rw-r--r--app/assets/javascripts/api.js.coffee1
-rw-r--r--app/assets/javascripts/application.js2
-rw-r--r--app/assets/javascripts/branch-graph.js.coffee95
-rw-r--r--app/assets/javascripts/commit.js.coffee6
-rw-r--r--app/assets/javascripts/dashboard.js.coffee83
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee40
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js.coffee2
-rw-r--r--app/assets/javascripts/main.js.coffee8
-rw-r--r--app/assets/javascripts/merge_requests.js.coffee7
-rw-r--r--app/assets/javascripts/project.js.coffee37
-rw-r--r--app/assets/javascripts/projects.js.coffee35
-rw-r--r--app/assets/javascripts/search_autocomplete.js.coffee8
-rw-r--r--app/assets/javascripts/tree.js.coffee41
-rw-r--r--app/assets/javascripts/wall.js.coffee42
-rw-r--r--app/assets/javascripts/wikis.js.coffee19
-rw-r--r--app/assets/stylesheets/application.scss1
-rw-r--r--app/assets/stylesheets/common.scss5
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/blocks.scss7
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/buttons.scss4
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/common.scss6
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/lists.scss9
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/nav.scss2
-rw-r--r--app/assets/stylesheets/highlight/monokai.scss86
-rw-r--r--app/assets/stylesheets/sections/commits.scss14
-rw-r--r--app/assets/stylesheets/sections/events.scss8
-rw-r--r--app/assets/stylesheets/sections/graph.scss3
-rw-r--r--app/assets/stylesheets/sections/notes.scss12
-rw-r--r--app/assets/stylesheets/sections/projects.scss8
-rw-r--r--app/assets/stylesheets/sections/tree.scss2
-rw-r--r--app/contexts/projects/create_context.rb17
-rw-r--r--app/controllers/application_controller.rb1
-rw-r--r--app/controllers/dashboard_controller.rb1
-rw-r--r--app/controllers/edit_tree_controller.rb2
-rw-r--r--app/controllers/milestones_controller.rb4
-rw-r--r--app/controllers/refs_controller.rb2
-rw-r--r--app/controllers/repositories_controller.rb4
-rw-r--r--app/helpers/application_helper.rb30
-rw-r--r--app/helpers/graph_helper.rb3
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/helpers/tree_helper.rb16
-rw-r--r--app/models/merge_request.rb26
-rw-r--r--app/models/network/graph.rb13
-rw-r--r--app/models/note.rb6
-rw-r--r--app/models/project.rb4
-rw-r--r--app/models/repository.rb16
-rw-r--r--app/services/notification_service.rb22
-rw-r--r--app/views/admin/groups/edit.html.haml2
-rw-r--r--app/views/admin/groups/new.html.haml2
-rw-r--r--app/views/admin/groups/show.html.haml17
-rw-r--r--app/views/admin/hooks/index.html.haml2
-rw-r--r--app/views/admin/teams/index.html.haml2
-rw-r--r--app/views/admin/teams/new.html.haml2
-rw-r--r--app/views/admin/teams/show.html.haml14
-rw-r--r--app/views/admin/users/_form.html.haml3
-rw-r--r--app/views/blob/_actions.html.haml2
-rw-r--r--app/views/blob/show.html.haml2
-rw-r--r--app/views/blob/show.js.haml10
-rw-r--r--app/views/commit/huge_commit.html.haml2
-rw-r--r--app/views/commit/show.html.haml7
-rw-r--r--app/views/commits/_text_file.html.haml2
-rw-r--r--app/views/commits/show.html.haml4
-rw-r--r--app/views/dashboard/_sidebar.html.haml5
-rw-r--r--app/views/dashboard/projects.html.haml13
-rw-r--r--app/views/dashboard/show.html.haml3
-rw-r--r--app/views/deploy_keys/index.html.haml2
-rw-r--r--app/views/devise/sessions/_new_ldap.html.haml26
-rw-r--r--app/views/graph/show.html.haml13
-rw-r--r--app/views/groups/show.html.haml8
-rw-r--r--app/views/issues/_form.html.haml2
-rw-r--r--app/views/issues/index.html.haml7
-rw-r--r--app/views/layouts/_head_panel.html.haml5
-rw-r--r--app/views/layouts/_search.html.haml9
-rw-r--r--app/views/layouts/admin.html.haml2
-rw-r--r--app/views/layouts/application.html.haml2
-rw-r--r--app/views/layouts/group.html.haml2
-rw-r--r--app/views/layouts/profile.html.haml2
-rw-r--r--app/views/layouts/project_resource.html.haml2
-rw-r--r--app/views/layouts/user_team.html.haml2
-rw-r--r--app/views/merge_requests/_form.html.haml2
-rw-r--r--app/views/merge_requests/_show.html.haml18
-rw-r--r--app/views/merge_requests/show/_how_to_merge.html.haml23
-rw-r--r--app/views/merge_requests/show/_mr_box.html.haml12
-rw-r--r--app/views/merge_requests/show/_mr_ci.html.haml2
-rw-r--r--app/views/milestones/_milestone.html.haml11
-rw-r--r--app/views/milestones/index.html.haml28
-rw-r--r--app/views/milestones/show.html.haml4
-rw-r--r--app/views/milestones/update.js.haml2
-rw-r--r--app/views/notes/_notes_with_form.html.haml4
-rw-r--r--app/views/notifications/show.html.haml6
-rw-r--r--app/views/profiles/design.html.haml5
-rw-r--r--app/views/profiles/show.html.haml2
-rw-r--r--app/views/projects/_clone_panel.html.haml40
-rw-r--r--app/views/projects/_form.html.haml9
-rw-r--r--app/views/projects/edit.html.haml3
-rw-r--r--app/views/projects/new.html.haml3
-rw-r--r--app/views/projects/show.html.haml35
-rw-r--r--app/views/projects/tree.js.haml5
-rw-r--r--app/views/repositories/stats.html.haml10
-rw-r--r--app/views/shared/_clone_panel.html.haml13
-rw-r--r--app/views/shared/_promo.html.haml4
-rw-r--r--app/views/team_members/_team.html.haml7
-rw-r--r--app/views/team_members/_team_member.html.haml6
-rw-r--r--app/views/team_members/create.js.haml13
-rw-r--r--app/views/teams/members/_show.html.haml37
-rw-r--r--app/views/teams/members/new.html.haml48
-rw-r--r--app/views/teams/show.html.haml8
-rw-r--r--app/views/tree/_tree.html.haml12
-rw-r--r--app/views/tree/show.js.haml10
-rw-r--r--app/views/walls/show.html.haml5
-rw-r--r--app/views/wikis/_nav.html.haml4
-rw-r--r--app/views/wikis/_new.html.haml21
-rw-r--r--app/workers/post_receive.rb27
-rw-r--r--config/aws.yml.example19
-rw-r--r--config/gitlab.yml.example9
-rw-r--r--config/initializers/1_settings.rb6
-rw-r--r--config/initializers/3_grit_ext.rb4
-rw-r--r--config/initializers/5_backend.rb3
-rw-r--r--config/initializers/carrierwave.rb16
-rw-r--r--config/unicorn.rb.example68
-rw-r--r--db/fixtures/development/02_source_code.rb4
-rw-r--r--doc/api/projects.md2
-rw-r--r--doc/api/users.md1
-rw-r--r--doc/install/installation.md27
-rw-r--r--doc/install/requirements.md5
-rw-r--r--doc/raketasks/maintenance.md82
-rw-r--r--doc/raketasks/user_management.md2
-rw-r--r--doc/update/2.6-to-3.0.md63
-rw-r--r--doc/update/2.9-to-3.0.md37
-rw-r--r--doc/update/3.0-to-3.1.md108
-rw-r--r--doc/update/3.1-to-4.0.md99
-rw-r--r--doc/update/4.0-to-4.1.md55
-rw-r--r--doc/update/4.1-to-4.2.md34
-rw-r--r--doc/update/4.2-to-5.0.md163
-rw-r--r--doc/update/5.0-to-5.1.md61
-rw-r--r--features/project/network.feature10
-rw-r--r--features/project/team_management.feature1
-rw-r--r--features/steps/project/project_network_graph.rb9
-rw-r--r--features/steps/project/project_team_management.rb18
-rw-r--r--lib/api/internal.rb3
-rw-r--r--lib/api/users.rb1
-rw-r--r--lib/extracts_path.rb4
-rw-r--r--lib/gitlab/backend/grack_auth.rb42
-rw-r--r--lib/gitlab/git/blame.rb22
-rw-r--r--lib/gitlab/git/blob.rb42
-rw-r--r--lib/gitlab/git/commit.rb121
-rw-r--r--lib/gitlab/git/compare.rb35
-rw-r--r--lib/gitlab/git/repository.rb201
-rw-r--r--lib/gitlab/git/stats.rb75
-rw-r--r--lib/gitlab/git/tree.rb52
-rw-r--r--lib/gitlab/identifier.rb23
-rw-r--r--lib/support/init.d/gitlab131
-rw-r--r--lib/support/nginx/gitlab38
-rw-r--r--lib/tasks/gitlab/backup.rake5
-rw-r--r--lib/tasks/gitlab/check.rake26
-rw-r--r--lib/tasks/gitlab/task_helpers.rake5
-rw-r--r--lib/tasks/migrate/migrate_milestones.rake4
-rw-r--r--lib/tasks/migrate/migrate_mr.rake7
-rw-r--r--spec/features/admin/admin_users_spec.rb12
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb40
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb123
-rw-r--r--spec/models/user_spec.rb8
-rw-r--r--spec/observers/merge_request_observer_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb2
-rw-r--r--spec/support/test_env.rb7
172 files changed, 2033 insertions, 1623 deletions
diff --git a/CHANGELOG b/CHANGELOG
index d4deb97099e..f01b5e87c5e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,15 @@
+v 5.2.0
+ - Turbolinks
+ - Git over http with ldap credentials
+ - Diff with better colors and some spacing on the corners
+ - Default values for project features
+ - Fixed huge_commit view
+ - Restyle project clone panel
+ - Move Gitlab::Git code to gitlab_git gem
+ - Move update docs in repo
+ - requires gitlab-shell v1.4.0
+ - fixed submodules listing under file tab
+
v 5.1.0
- You can login with email or username now
- Corrected project transfer rollback when repository cannot be moved
@@ -11,7 +23,16 @@ v 5.1.0
- Restyled Issues list. Show milestone version in issue row
- Restyled Merge Request list
- Backup now dump/restore uploads
- - Improved perfomance of dashboard
+ - Improved perfomance of dashboard (Andrew Kumanyaev)
+ - File history now tracks renames (Akzhan Abdulin)
+ - Drop wiki migration tools
+ - Drop sqlite migration tools
+ - project tagging
+ - Paginate users in API
+ - Restyled network graph (Hiroyuki Sato)
+
+v 5.0.1
+ - Fixed issue with gitlab-grit being overrided by grit
v 5.0.0
- Replaced gitolite with gitlab-shell
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f322a81ca5a..79e57558084 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,10 +1,31 @@
# Contribute to GitLab
-This guide details how to use pull requests and the issues to improve GitLab.
+This guide details how to use issues and pull requests to improve GitLab.
-## Closing policy for pull requests and issues
+## Closing policy for issues and pull requests
-Pull requests and issues not in line with the guidelines listed in this document will be closed with just a link to this paragraph. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. To get support for your problems please use other channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
+Issues and pull requests not in line with the guidelines listed in this document will be closed with just a link to this paragraph. GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. To get support for your problems please use other channels as detailed in [the getting help section of the readme](https://github.com/gitlabhq/gitlabhq#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
+
+## Issue tracker
+
+The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
+
+Do not use the issue tracker for feature requests. We have a specific
+[Feedback and suggestions forum](http://feedback.gitlab.com) for this purpose.
+
+Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
+
+### Issue tracker guidelines
+
+**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
+
+* Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
+* Describe your issue in detail
+* How can we reproduce the issue on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: vagrant destroy && vagrant up && vagrant ssh)
+* Add the last commit sha1 of the GitLab version you used to replicate the issue
+* Add logs or screen shots when possible
+* Link to the line of code that might be responsible for the problem
+* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
## Pull requests
@@ -33,21 +54,3 @@ We will accept pull requests if:
* If it makes changes to the UI the pull request should include screenshots
For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed).
-
-## Issue tracker
-
-The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
-
-Please send a pull request with a tested solution or a pull request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [Support Forum](https://groups.google.com/forum/#!forum/gitlabhq) first. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there.
-
-### Issue tracker guidelines
-
-**Search** for similar entries before submitting your own, there's a good chance somebody else had the same issue or idea. Show your support with `:+1:` and/or join the discussion.
-
-* Summarize your issue in one sentence (what goes wrong, what did you expect to happen)
-* Describe your issue in detail
-* How can we reproduce the issue on the [GitLab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm) (start with: vagrant destroy && vagrant up && vagrant ssh)
-* Add the last commit sha1 of the GitLab version you used to replicate the issue
-* Add logs or screen shots when possible
-* Link to the line of code that might be responsible for the problem
-* Describe your setup (use relevant parts from `sudo -u gitlab -H bundle exec rake gitlab:env:info`)
diff --git a/Gemfile b/Gemfile
index 71ac795772a..bccde6664dd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -22,9 +22,9 @@ gem 'omniauth-twitter'
gem 'omniauth-github'
# Extracting information from a git repository
-# Since gollum requires grit we cannot use gitlab-grit gem name any more. Use grit instead
+# We cannot use original git since some bugs
gem "grit", '~> 2.5.0', git: 'https://github.com/gitlabhq/grit.git', ref: '42297cdcee16284d2e4eff23d41377f52fc28b9d'
-gem 'grit_ext', '~> 0.8.1'
+gem 'gitlab_git', '~> 1.0.6'
# Ruby/Rack Git Smart-HTTP Server Handler
gem 'gitlab-grack', '~> 1.0.0', require: 'grack'
@@ -36,11 +36,11 @@ gem 'gitlab_omniauth-ldap', '1.0.2', require: "omniauth-ldap"
gem "gitlab-pygments.rb", '~> 0.3.2', require: 'pygments.rb'
# Language detection
-gem "github-linguist", "~> 2.3.4" , require: "linguist"
+gem "github-linguist", require: "linguist"
# API
-gem "grape", "~> 0.3.1"
-gem "grape-entity", "~> 0.2.0"
+gem "grape"
+gem "grape-entity"
# Format dates and times
# based on human-friendly examples
@@ -57,6 +57,8 @@ gem "haml-rails"
# Files attachments
gem "carrierwave"
+# for aws storage
+# gem "fog", "~> 1.3.1"
# Authorization
gem "six"
@@ -69,13 +71,13 @@ gem "redcarpet", "~> 2.2.2"
gem "github-markup", "~> 0.7.4", require: 'github/markup'
# Servers
-gem "puma", '~> 2.0.0.b7'
+gem "puma", '~> 2.0.1'
# State machine
gem "state_machine"
# Issue tags
-gem "acts-as-taggable-on", "2.3.3"
+gem "acts-as-taggable-on"
# Background jobs
gem 'slim'
@@ -101,10 +103,12 @@ gem "foreman"
gem "redis-rails"
group :assets do
- gem "sass-rails", "~> 3.2.5"
- gem "coffee-rails", "~> 3.2.2"
- gem "uglifier", "~> 1.3.0"
+ gem "sass-rails"
+ gem "coffee-rails"
+ gem "uglifier"
gem "therubyracer"
+ gem 'turbolinks'
+ gem 'jquery-turbolinks'
gem 'chosen-rails', "0.9.8"
gem 'select2-rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index c8d75f9dc89..c06a1bd09cc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/ctran/annotate_models.git
- revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
+ revision: 8bd159c7a484093fde84beaa9e6398f25ddacf09
specs:
annotate (2.6.0.beta1)
activerecord (>= 2.3.0)
@@ -62,16 +62,16 @@ GEM
activesupport (3.2.13)
i18n (= 0.6.1)
multi_json (~> 1.0)
- acts-as-taggable-on (2.3.3)
+ acts-as-taggable-on (2.4.0)
rails (~> 3.0)
- addressable (2.3.2)
+ addressable (2.3.4)
arel (3.0.2)
awesome_print (1.1.0)
backports (2.6.7)
bcrypt-ruby (3.0.1)
- better_errors (0.3.2)
+ better_errors (0.8.0)
coderay (>= 1.0.0)
- erubis (>= 2.7.0)
+ erubis (>= 2.6.6)
binding_of_caller (0.7.1)
debug_inspector (>= 0.0.1)
bootstrap-sass (2.2.1.1)
@@ -86,10 +86,9 @@ GEM
carrierwave (0.8.0)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
- celluloid (0.12.4)
- facter (>= 1.6.12)
+ celluloid (0.13.0)
timers (>= 1.0.0)
- charlock_holmes (0.6.9)
+ charlock_holmes (0.6.9.4)
chosen-rails (0.9.8)
railties (~> 3.0)
thor (~> 0.14)
@@ -102,11 +101,11 @@ GEM
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.4.0)
+ coffee-script-source (1.6.2)
colored (1.2)
colorize (0.5.8)
connection_pool (1.0.0)
- coveralls (0.6.2)
+ coveralls (0.6.7)
colorize
multi_json (~> 1.3)
rest-client
@@ -122,7 +121,8 @@ GEM
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
- diff-lcs (1.2.1)
+ diff-lcs (1.2.4)
+ dotenv (0.7.0)
email_spec (1.4.0)
launchy (~> 2.1)
mail (~> 2.2)
@@ -130,28 +130,29 @@ GEM
activesupport (>= 3.2)
erubis (2.7.0)
escape_utils (0.2.4)
- eventmachine (1.0.0)
+ eventmachine (1.0.3)
execjs (1.4.0)
multi_json (~> 1.0)
- facter (1.6.18)
- factory_girl (4.1.0)
+ factory_girl (4.2.0)
activesupport (>= 3.0.0)
- factory_girl_rails (4.1.0)
- factory_girl (~> 4.1.0)
+ factory_girl_rails (4.2.1)
+ factory_girl (~> 4.2.0)
railties (>= 3.0.0)
- faraday (0.8.6)
+ faraday (0.8.7)
multipart-post (~> 1.1)
faye-websocket (0.4.7)
eventmachine (>= 0.12.0)
- ffaker (1.15.0)
- ffi (1.6.0)
+ ffaker (1.16.0)
+ ffi (1.8.1)
font-awesome-sass-rails (3.0.2.2)
railties (>= 3.1.1)
sass-rails (>= 3.1.1)
- foreman (0.62.0)
+ foreman (0.63.0)
+ dotenv (>= 0.7)
thor (>= 0.13.6)
+ formatador (0.2.4)
gemoji (1.2.1)
- gherkin-ruby (0.2.1)
+ gherkin-ruby (0.3.0)
github-linguist (2.3.4)
charlock_holmes (~> 0.6.6)
escape_utils (~> 0.2.3)
@@ -164,6 +165,11 @@ GEM
gitlab-pygments.rb (0.3.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
+ gitlab_git (1.0.6)
+ activesupport (~> 3.2.13)
+ github-linguist (~> 2.3.4)
+ grit (~> 2.5.0)
+ grit_ext (~> 0.8.1)
gitlab_meta (5.0)
gitlab_omniauth-ldap (1.0.2)
net-ldap (~> 0.2.2)
@@ -178,46 +184,48 @@ GEM
pygments.rb (~> 0.4.2)
sanitize (~> 2.0.3)
stringex (~> 1.5.1)
- gon (4.0.2)
- grape (0.3.2)
+ gon (4.1.0)
+ actionpack (>= 2.3.0)
+ json
+ grape (0.4.1)
activesupport
builder
hashie (>= 1.2.0)
multi_json (>= 1.3.2)
multi_xml (>= 0.5.2)
- rack
+ rack (>= 1.3.0)
rack-accept
rack-mount
virtus
- grape-entity (0.2.0)
+ grape-entity (0.3.0)
activesupport
multi_json (>= 1.3.2)
grit_ext (0.8.1)
charlock_holmes (~> 0.6.9)
growl (1.0.3)
- guard (1.6.2)
- listen (>= 0.6.0)
+ guard (1.8.0)
+ formatador (>= 0.2.4)
+ listen (>= 1.0.0)
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
- terminal-table (>= 1.4.3)
thor (>= 0.14.6)
- guard-rspec (2.5.1)
- guard (>= 1.1)
- rspec (~> 2.11)
+ guard-rspec (2.6.0)
+ guard (>= 1.8)
+ rspec (~> 2.13)
guard-spinach (0.0.2)
guard (>= 1.1)
spinach
- haml (4.0.0)
+ haml (4.0.2)
tilt
haml-rails (0.4)
actionpack (>= 3.1, < 4.1)
activesupport (>= 3.1, < 4.1)
haml (>= 3.1, < 4.1)
railties (>= 3.1, < 4.1)
- hashie (1.2.0)
+ hashie (2.0.4)
hike (1.2.2)
http_parser.rb (0.5.3)
- httparty (0.10.2)
+ httparty (0.11.0)
multi_json (~> 1.0)
multi_xml (>= 0.5.2)
httpauth (0.2.0)
@@ -227,33 +235,39 @@ GEM
jquery-rails (2.1.3)
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
+ jquery-turbolinks (1.0.0)
+ railties (>= 3.1.0)
+ turbolinks
jquery-ui-rails (2.0.2)
jquery-rails
railties (>= 3.1.0)
json (1.7.7)
- jwt (0.1.5)
- multi_json (>= 1.0)
+ jwt (0.1.8)
+ multi_json (>= 1.5)
kaminari (0.14.1)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
- launchy (2.1.2)
+ launchy (2.2.0)
addressable (~> 2.3)
- letter_opener (1.0.0)
- launchy (>= 2.0.4)
+ letter_opener (1.1.0)
+ launchy (~> 2.2.0)
libv8 (3.11.8.17)
- listen (0.7.3)
+ listen (1.0.3)
+ rb-fsevent (>= 0.9.3)
+ rb-inotify (>= 0.9)
+ rb-kqueue (>= 0.2)
lumberjack (1.0.3)
mail (2.5.3)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.8.1)
- mime-types (1.22)
+ mime-types (1.23)
modernizr (2.6.2)
sprockets (~> 2.0)
multi_json (1.7.2)
multi_xml (0.5.3)
- multipart-post (1.1.5)
+ multipart-post (1.2.0)
mysql2 (0.3.11)
net-ldap (0.2.2)
nokogiri (1.5.9)
@@ -264,13 +278,13 @@ GEM
jwt (~> 0.1.4)
multi_json (~> 1.0)
rack (~> 1.2)
- omniauth (1.1.3)
- hashie (~> 1.2)
+ omniauth (1.1.4)
+ hashie (>= 1.2, < 3)
rack
omniauth-github (1.1.0)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1)
- omniauth-google-oauth2 (0.1.13)
+ omniauth-google-oauth2 (0.1.17)
omniauth (~> 1.0)
omniauth-oauth2
omniauth-oauth (1.0.1)
@@ -279,31 +293,31 @@ GEM
omniauth-oauth2 (1.1.1)
oauth2 (~> 0.8.0)
omniauth (~> 1.0)
- omniauth-twitter (0.0.14)
+ omniauth-twitter (0.0.16)
multi_json (~> 1.3)
omniauth-oauth (~> 1.0)
orm_adapter (0.4.0)
- pg (0.14.1)
+ pg (0.15.1)
polyglot (0.3.3)
posix-spawn (0.3.6)
- pry (0.9.12)
+ pry (0.9.12.1)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
- puma (2.0.0.b7)
+ puma (2.0.1)
rack (>= 1.1, < 2.0)
pygments.rb (0.4.2)
posix-spawn (~> 0.3.6)
yajl-ruby (~> 1.1.0)
pyu-ruby-sasl (0.0.3.3)
- quiet_assets (1.0.1)
- railties (~> 3.1)
+ quiet_assets (1.0.2)
+ railties (>= 3.1, < 5.0)
rack (1.4.5)
rack-accept (0.4.5)
rack (>= 0.4)
rack-cache (1.2)
rack (>= 0.4)
- rack-mini-profiler (0.1.23)
+ rack-mini-profiler (0.1.26)
rack (>= 1.1.3)
rack-mount (0.8.3)
rack (>= 1.0.0)
@@ -340,13 +354,15 @@ GEM
rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0)
rake (10.0.4)
- rb-fsevent (0.9.2)
- rb-inotify (0.8.8)
+ rb-fsevent (0.9.3)
+ rb-inotify (0.9.0)
+ ffi (>= 0.5.0)
+ rb-kqueue (0.2.0)
ffi (>= 0.5.0)
rdoc (3.12.2)
json (~> 1.4)
redcarpet (2.2.2)
- redis (3.0.3)
+ redis (3.0.4)
redis-actionpack (3.2.3)
actionpack (~> 3.2.3)
redis-rack (~> 1.4.0)
@@ -375,8 +391,8 @@ GEM
rspec-core (2.13.1)
rspec-expectations (2.13.0)
diff-lcs (>= 1.1.3, < 2.0)
- rspec-mocks (2.13.0)
- rspec-rails (2.13.0)
+ rspec-mocks (2.13.1)
+ rspec-rails (2.13.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
@@ -387,7 +403,7 @@ GEM
rubyntlm (0.1.1)
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
- sass (3.2.7)
+ sass (3.2.8)
sass-rails (3.2.6)
railties (~> 3.2.0)
sass (>= 3.1.10)
@@ -402,11 +418,11 @@ GEM
sass-rails (>= 3.2)
thor (~> 0.14)
settingslogic (2.0.9)
- sexp_processor (4.2.0)
+ sexp_processor (4.2.1)
shoulda-matchers (1.3.0)
activesupport (>= 3.0.0)
- sidekiq (2.9.0)
- celluloid (~> 0.12.0)
+ sidekiq (2.11.1)
+ celluloid (~> 0.13.0)
connection_pool (~> 1.0)
multi_json (~> 1)
redis (~> 3)
@@ -420,15 +436,15 @@ GEM
rack-protection (~> 1.3)
tilt (~> 1.3, >= 1.3.3)
six (0.2.0)
- slim (1.3.6)
- temple (~> 0.5.5)
+ slim (1.3.8)
+ temple (~> 0.6.3)
tilt (~> 1.3.3)
slop (3.4.4)
- spinach (0.8.1)
+ spinach (0.8.2)
colorize (= 0.5.8)
- gherkin-ruby (~> 0.2.1)
- spinach-rails (0.1.7)
- capybara (>= 1.0)
+ gherkin-ruby (~> 0.3.0)
+ spinach-rails (0.2.1)
+ capybara (>= 2.0.0)
railties (>= 3)
spinach (>= 0.4)
spork (1.0.0rc3)
@@ -438,15 +454,14 @@ GEM
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
stamp (0.5.0)
- state_machine (1.1.2)
+ state_machine (1.2.0)
stringex (1.5.1)
- temple (0.5.5)
- terminal-table (1.4.5)
- test_after_commit (0.0.1)
+ temple (0.6.4)
+ test_after_commit (0.2.0)
therubyracer (0.11.4)
libv8 (~> 3.11.8.12)
ref
- thin (1.5.0)
+ thin (1.5.1)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
@@ -456,8 +471,10 @@ GEM
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
+ turbolinks (1.1.1)
+ coffee-rails
tzinfo (0.3.37)
- uglifier (1.3.0)
+ uglifier (2.0.1)
execjs (>= 0.3.0)
multi_json (~> 1.0, >= 1.0.2)
virtus (0.5.4)
@@ -465,9 +482,9 @@ GEM
descendants_tracker (~> 0.0.1)
warden (1.2.1)
rack (>= 1.0)
- webmock (1.9.0)
+ webmock (1.11.0)
addressable (>= 2.2.7)
- crack (>= 0.1.7)
+ crack (>= 0.3.2)
xpath (2.0.0)
nokogiri (~> 1.3)
yajl-ruby (1.1.0)
@@ -476,7 +493,7 @@ PLATFORMS
ruby
DEPENDENCIES
- acts-as-taggable-on (= 2.3.3)
+ acts-as-taggable-on
annotate!
awesome_print
better_errors
@@ -485,7 +502,7 @@ DEPENDENCIES
capybara
carrierwave
chosen-rails (= 0.9.8)
- coffee-rails (~> 3.2.2)
+ coffee-rails
colored
coveralls
database_cleaner
@@ -497,18 +514,18 @@ DEPENDENCIES
font-awesome-sass-rails (~> 3.0.0)
foreman
gemoji (~> 1.2.1)
- github-linguist (~> 2.3.4)
+ github-linguist
github-markup (~> 0.7.4)
gitlab-grack (~> 1.0.0)
gitlab-pygments.rb (~> 0.3.2)
+ gitlab_git (~> 1.0.6)
gitlab_meta (= 5.0)
gitlab_omniauth-ldap (= 1.0.2)
gollum-lib (~> 1.0.0)
gon
- grape (~> 0.3.1)
- grape-entity (~> 0.2.0)
+ grape
+ grape-entity
grit (~> 2.5.0)!
- grit_ext (~> 0.8.1)
growl
guard-rspec
guard-spinach
@@ -516,6 +533,7 @@ DEPENDENCIES
httparty
jquery-atwho-rails (= 0.1.7)
jquery-rails (= 2.1.3)
+ jquery-turbolinks
jquery-ui-rails (= 2.0.2)
kaminari (~> 0.14.1)
launchy
@@ -529,7 +547,7 @@ DEPENDENCIES
pg
poltergeist!
pry
- puma (~> 2.0.0.b7)
+ puma (~> 2.0.1)
quiet_assets (~> 1.0.1)
rack-mini-profiler
rails (= 3.2.13)
@@ -541,7 +559,7 @@ DEPENDENCIES
redcarpet (~> 2.2.2)
redis-rails
rspec-rails
- sass-rails (~> 3.2.5)
+ sass-rails
sdoc
seed-fu
select2-rails
@@ -559,5 +577,6 @@ DEPENDENCIES
test_after_commit
therubyracer
thin
- uglifier (~> 1.3.0)
+ turbolinks
+ uglifier
webmock
diff --git a/README.md b/README.md
index fa9cf817469..f3af521a779 100644
--- a/README.md
+++ b/README.md
@@ -49,18 +49,14 @@
#### Official production installation
-Follow the installation guide for production server.
-
-* [Installation guide for latest stable release (5.0)](https://github.com/gitlabhq/gitlabhq/blob/5-0-stable/doc/install/installation.md) - **Recommended**
-
-* [Installation guide for the current master branch (5.1)](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
+* [Installation guide for a production server](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
#### Official development installation
If you want to contribute, please first read our [Contributing Guidelines](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) and then we suggest you to use the Vagrant virtual machine project to get an environment working with all dependencies.
-* [Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm)
+* [Vagrant virtual machine for development](https://github.com/gitlabhq/gitlab-vagrant-vm)
#### Unsupported production installation
@@ -78,7 +74,7 @@ If you want to contribute, please first read our [Contributing Guidelines](https
Each month on the 22th a new version is released together with an upgrade guide.
-* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/wiki)
+* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/tree/master/doc/update)
* [Changelog](https://github.com/gitlabhq/gitlabhq/blob/master/CHANGELOG)
@@ -143,13 +139,13 @@ Start it with [Foreman](https://github.com/ddollar/foreman)
* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq) is the best place to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and had it resolved. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
-* [Feedback and suggestions forum](http://gitlab.uservoice.com/forums/176466-general) is the place to propose and discuss new features for GitLab.
+* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab.
* [Support subscription](http://www.gitlab.com/subscription/) connect you to the knowledge of GitLab experts that will resolve your issues and answer your questions.
-* [Consultancy](http://www.gitlab.com/consultancy/) allows you hire GitLab exports for installations, upgrades and customizations.
+* [Consultancy](http://www.gitlab.com/consultancy/) allows you hire GitLab experts for installations, upgrades and customizations.
-* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed without comment.
+* [Contributing guide](https://github.com/gitlabhq/gitlabhq/blob/master/CONTRIBUTING.md) describes how to submit pull requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed.
### Getting in touch
diff --git a/VERSION b/VERSION
index 52df2a23917..ffee65a410e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.1.0pre
+5.2.0.pre
diff --git a/app/assets/images/monokai.png b/app/assets/images/monokai.png
new file mode 100644
index 00000000000..9477941778e
--- /dev/null
+++ b/app/assets/images/monokai.png
Binary files differ
diff --git a/app/assets/javascripts/admin.js.coffee b/app/assets/javascripts/admin.js.coffee
index 1dafdf4bd8b..c83b74a76a2 100644
--- a/app/assets/javascripts/admin.js.coffee
+++ b/app/assets/javascripts/admin.js.coffee
@@ -1,17 +1,30 @@
-$ ->
- $('input#user_force_random_password').on 'change', (elem) ->
- elems = $('#user_password, #user_password_confirmation')
+class Admin
+ constructor: ->
+ $('input#user_force_random_password').on 'change', (elem) ->
+ elems = $('#user_password, #user_password_confirmation')
- if $(@).attr 'checked'
- elems.val('').attr 'disabled', true
- else
- elems.removeAttr 'disabled'
+ if $(@).attr 'checked'
+ elems.val('').attr 'disabled', true
+ else
+ elems.removeAttr 'disabled'
- $('.log-tabs a').click (e) ->
- e.preventDefault()
- $(this).tab('show')
+ $('.log-tabs a').click (e) ->
+ e.preventDefault()
+ $(this).tab('show')
- $('.log-bottom').click (e) ->
- e.preventDefault()
- visible_log = $(".file_content:visible")
- visible_log.animate({ scrollTop: visible_log.find('ol').height() }, "fast")
+ $('.log-bottom').click (e) ->
+ e.preventDefault()
+ visible_log = $(".file_content:visible")
+ visible_log.animate({ scrollTop: visible_log.find('ol').height() }, "fast")
+
+ modal = $('.change-owner-holder')
+
+ $('.change-owner-link').bind "click", ->
+ $(this).hide()
+ modal.show()
+
+ $('.change-owner-cancel-link').bind "click", ->
+ modal.hide()
+ $('.change-owner-link').show()
+
+@Admin = Admin
diff --git a/app/assets/javascripts/api.js.coffee b/app/assets/javascripts/api.js.coffee
index ca721517867..7cac971f247 100644
--- a/app/assets/javascripts/api.js.coffee
+++ b/app/assets/javascripts/api.js.coffee
@@ -50,4 +50,5 @@
callback(users)
buildUrl: (url) ->
+ url = gon.relative_url_root + url if gon.relative_url_root.present?
return url.replace(':version', gon.api_version)
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index adb4009fbc2..bbec12ad08c 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -14,6 +14,8 @@
//= require jquery.waitforimages
//= require jquery.atwho
//= require jquery.scrollto
+//= require turbolinks
+//= require jquery.turbolinks
//= require bootstrap
//= require modernizr
//= require chosen-jquery
diff --git a/app/assets/javascripts/branch-graph.js.coffee b/app/assets/javascripts/branch-graph.js.coffee
index 2a668de278a..c12e672d666 100644
--- a/app/assets/javascripts/branch-graph.js.coffee
+++ b/app/assets/javascripts/branch-graph.js.coffee
@@ -9,6 +9,7 @@ class BranchGraph
@offsetY = 20
@unitTime = 30
@unitSpace = 10
+ @prev_start = -1
@load()
load: ->
@@ -24,10 +25,18 @@ class BranchGraph
prepareData: (@days, @commits) ->
@collectParents()
+ @graphHeight = $(@element).height()
+ @graphWidth = $(@element).width()
+ ch = Math.max(@graphHeight, @offsetY + @unitTime * @mtime + 150)
+ cw = Math.max(@graphWidth, @offsetX + @unitSpace * @mspace + 300)
+ @r = Raphael(@element.get(0), cw, ch)
+ @top = @r.set()
+ @barHeight = Math.max(@graphHeight, @unitTime * @days.length + 320)
for c in @commits
c.isParent = true if c.id of @parents
@preparedCommits[c.id] = c
+ @markCommit(c)
@collectColors()
@@ -49,18 +58,12 @@ class BranchGraph
k++
buildGraph: ->
- graphHeight = $(@element).height()
- graphWidth = $(@element).width()
- ch = Math.max(graphHeight, @offsetY + @unitTime * @mtime + 150)
- cw = Math.max(graphWidth, @offsetX + @unitSpace * @mspace + 300)
- @r = r = Raphael(@element.get(0), cw, ch)
- top = r.set()
+ r = @r
cuday = 0
cumonth = ""
- barHeight = Math.max(graphHeight, @unitTime * @days.length + 320)
- r.rect(0, 0, 26, barHeight).attr fill: "#222"
- r.rect(26, 0, 20, barHeight).attr fill: "#444"
+ r.rect(0, 0, 26, @barHeight).attr fill: "#222"
+ r.rect(26, 0, 20, @barHeight).attr fill: "#444"
for day, mm in @days
if cuday isnt day[0]
@@ -81,42 +84,50 @@ class BranchGraph
)
cumonth = day[1]
- for commit in @commits
- x = @offsetX + @unitSpace * (@mspace - commit.space)
- y = @offsetY + @unitTime * commit.time
+ @renderPartialGraph()
+
+ @bindEvents()
- @drawDot(x, y, commit)
+ renderPartialGraph: ->
+ start = Math.floor((@element.scrollTop() - @offsetY) / @unitTime) - 10
+ start = 0 if start < 0
+ end = start + 40
+ end = @commits.length if @commits.length < end
- @drawLines(x, y, commit)
+ if @prev_start == -1 or Math.abs(@prev_start - start) > 10
+ i = start
- @appendLabel(x, y, commit.refs) if commit.refs
+ @prev_start = start
- @appendAnchor(top, commit, x, y)
+ while i < end
+ commit = @commits[i]
+ i += 1
- @markCommit(x, y, commit, graphHeight)
+ if commit.hasDrawn isnt true
+ x = @offsetX + @unitSpace * (@mspace - commit.space)
+ y = @offsetY + @unitTime * commit.time
- top.toFront()
- @bindEvents()
+ @drawDot(x, y, commit)
+
+ @drawLines(x, y, commit)
+
+ @appendLabel(x, y, commit)
+
+ @appendAnchor(x, y, commit)
+
+ commit.hasDrawn = true
+
+ @top.toFront()
bindEvents: ->
drag = {}
element = @element
- dragger = (event) ->
- element.scrollLeft drag.sl - (event.clientX - drag.x)
- element.scrollTop drag.st - (event.clientY - drag.y)
-
- element.on mousedown: (event) ->
- drag =
- x: event.clientX
- y: event.clientY
- st: element.scrollTop()
- sl: element.scrollLeft()
- $(window).on "mousemove", dragger
+
+ $(element).scroll (event) =>
+ @renderPartialGraph()
$(window).on
- mouseup: ->
- $(window).off "mousemove", dragger
- keydown: (event) ->
+ keydown: (event) =>
# left
element.scrollLeft element.scrollLeft() - 50 if event.keyCode is 37
# top
@@ -125,17 +136,20 @@ class BranchGraph
element.scrollLeft element.scrollLeft() + 50 if event.keyCode is 39
# bottom
element.scrollTop element.scrollTop() + 50 if event.keyCode is 40
+ @renderPartialGraph()
+
+ appendLabel: (x, y, commit) ->
+ return unless commit.refs
- appendLabel: (x, y, refs) ->
r = @r
- shortrefs = refs
+ shortrefs = commit.refs
# Truncate if longer than 15 chars
shortrefs = shortrefs.substr(0, 15) + "…" if shortrefs.length > 17
text = r.text(x + 4, y, shortrefs).attr(
"text-anchor": "start"
font: "10px Monaco, monospace"
fill: "#FFF"
- title: refs
+ title: commit.refs
)
textbox = text.getBBox()
# Create rectangle based on the size of the textbox
@@ -156,8 +170,9 @@ class BranchGraph
# Set text to front
text.toFront()
- appendAnchor: (top, commit, x, y) ->
+ appendAnchor: (x, y, commit) ->
r = @r
+ top = @top
options = @options
anchor = r.circle(x, y, 10).attr(
fill: "#000"
@@ -240,16 +255,18 @@ class BranchGraph
stroke: color
"stroke-width": 2)
- markCommit: (x, y, commit, graphHeight) ->
+ markCommit: (commit) ->
if commit.id is @options.commit_id
r = @r
+ x = @offsetX + @unitSpace * (@mspace - commit.space)
+ y = @offsetY + @unitTime * commit.time
r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr(
fill: "#000"
"fill-opacity": .5
stroke: "none"
)
# Displayed in the center
- @element.scrollTop(y - graphHeight / 2)
+ @element.scrollTop(y - @graphHeight / 2)
Raphael::commitTooltip = (x, y, commit) ->
boxWidth = 300
diff --git a/app/assets/javascripts/commit.js.coffee b/app/assets/javascripts/commit.js.coffee
new file mode 100644
index 00000000000..9f55a1e6368
--- /dev/null
+++ b/app/assets/javascripts/commit.js.coffee
@@ -0,0 +1,6 @@
+class Commit
+ constructor: ->
+ $('.files .file').each ->
+ new CommitFile(this)
+
+@Commit = Commit
diff --git a/app/assets/javascripts/dashboard.js.coffee b/app/assets/javascripts/dashboard.js.coffee
index 4189c90bbfa..9beca261467 100644
--- a/app/assets/javascripts/dashboard.js.coffee
+++ b/app/assets/javascripts/dashboard.js.coffee
@@ -1,39 +1,44 @@
-window.dashboardPage = ->
- Pager.init 20, true
- initSidebarTab()
- $(".event_filter_link").bind "click", (event) ->
- event.preventDefault()
- toggleFilter $(this)
- reloadActivities()
-
-reloadActivities = ->
- $(".content_list").html ''
- Pager.init 20, true
-
-toggleFilter = (sender) ->
- sender.parent().toggleClass "inactive"
- event_filters = $.cookie("event_filter")
- filter = sender.attr("id").split("_")[0]
- if event_filters
- event_filters = event_filters.split(",")
- else
- event_filters = new Array()
-
- index = event_filters.indexOf(filter)
- if index is -1
- event_filters.push filter
- else
- event_filters.splice index, 1
-
- $.cookie "event_filter", event_filters.join(",")
-
-initSidebarTab = ->
- key = "dashboard_sidebar_filter"
-
- # store selection in cookie
- $('.dash-sidebar-tabs a').on 'click', (e) ->
- $.cookie(key, $(e.target).attr('id'))
-
- # show tab from cookie
- sidebar_filter = $.cookie(key)
- $("#" + sidebar_filter).tab('show') if sidebar_filter
+class Dashboard
+ constructor: ->
+ Pager.init 20, true
+ @initSidebarTab()
+
+ $(".event_filter_link").bind "click", (event) =>
+ event.preventDefault()
+ @toggleFilter($(event.currentTarget))
+ @reloadActivities()
+
+ reloadActivities: ->
+ $(".content_list").html ''
+ Pager.init 20, true
+
+ toggleFilter: (sender) ->
+ sender.parent().toggleClass "inactive"
+ event_filters = $.cookie("event_filter")
+ filter = sender.attr("id").split("_")[0]
+ if event_filters
+ event_filters = event_filters.split(",")
+ else
+ event_filters = new Array()
+
+ index = event_filters.indexOf(filter)
+ if index is -1
+ event_filters.push filter
+ else
+ event_filters.splice index, 1
+
+ $.cookie "event_filter", event_filters.join(",")
+
+ initSidebarTab: ->
+ key = "dashboard_sidebar_filter"
+
+ # store selection in cookie
+ $('.dash-sidebar-tabs a').on 'click', (e) ->
+ $.cookie(key, $(e.target).attr('id'))
+
+ # show tab from cookie
+ sidebar_filter = $.cookie(key)
+ $("#" + sidebar_filter).tab('show') if sidebar_filter
+
+
+@Dashboard = Dashboard
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
new file mode 100644
index 00000000000..6e2d1592e32
--- /dev/null
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -0,0 +1,40 @@
+$ ->
+ new Dispatcher()
+
+class Dispatcher
+ constructor: () ->
+ @initSearch()
+ @initPageScripts()
+
+ initPageScripts: ->
+ page = $('body').attr('data-page')
+ project_id = $('body').attr('data-project-id')
+
+ console.log(page)
+
+ unless page
+ return false
+
+ path = page.split(':')
+
+ switch page
+ when 'issues:index'
+ Issues.init()
+ when 'dashboard:show'
+ new Dashboard()
+ when 'commit:show'
+ new Commit()
+ when 'groups:show', 'teams:show', 'projects:show'
+ Pager.init(20, true)
+ when 'projects:new', 'projects:edit'
+ new Project()
+ when 'walls:show'
+ new Wall(project_id)
+
+ switch path.first()
+ when 'admin' then new Admin()
+ when 'wikis' then new Wikis()
+
+ initSearch: ->
+ autocomplete_json = $('.search-autocomplete-json').data('autocomplete-opts')
+ new SearchAutocomplete(autocomplete_json)
diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee
index 1cc9d34dd80..9ef194fbd25 100644
--- a/app/assets/javascripts/gfm_auto_complete.js.coffee
+++ b/app/assets/javascripts/gfm_auto_complete.js.coffee
@@ -20,7 +20,7 @@ GitLab.GfmAutoComplete =
input = $('.js-gfm-input')
# Emoji
- input.atWho ':',
+ input.atWho '(?:^|\\s):',
data: @Emoji.data
tpl: @Emoji.template
diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee
index 39ec86e623f..fb51d379ebd 100644
--- a/app/assets/javascripts/main.js.coffee
+++ b/app/assets/javascripts/main.js.coffee
@@ -41,6 +41,14 @@ window.linkify = (str) ->
exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
return str.replace(exp,"<a href='$1'>$1</a>")
+window.startSpinner = ->
+ $('.turbolink-spinner').fadeIn()
+
+window.stopSpinner = ->
+ $('.turbolink-spinner').fadeOut()
+
+document.addEventListener("page:fetch", startSpinner)
+document.addEventListener("page:receive", stopSpinner)
$ ->
# Click a .one_click_select field, select the contents
diff --git a/app/assets/javascripts/merge_requests.js.coffee b/app/assets/javascripts/merge_requests.js.coffee
index 9ab41f9ac1b..769a940959b 100644
--- a/app/assets/javascripts/merge_requests.js.coffee
+++ b/app/assets/javascripts/merge_requests.js.coffee
@@ -21,6 +21,13 @@ class MergeRequest
this.initMergeWidget()
this.$('.show-all-commits').on 'click', =>
this.showAllCommits()
+
+ modal = $('#modal_merge_info').modal modal: true, show:false
+
+ $('.how_to_merge_link').bind "click", ->
+ modal.show()
+ $('.modal-header .close').bind "click", ->
+ modal.hide()
# Local jQuery finder
$: (selector) ->
diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee
new file mode 100644
index 00000000000..f926188d23f
--- /dev/null
+++ b/app/assets/javascripts/project.js.coffee
@@ -0,0 +1,37 @@
+class Project
+ constructor: ->
+ $('.new_project, .edit_project').on 'ajax:before', ->
+ $('.project_new_holder, .project_edit_holder').hide()
+ $('.save-project-loader').show()
+
+ $('form #project_default_branch').chosen()
+ disableButtonIfEmptyField '#project_name', '.project-submit'
+
+ $('#project_issues_enabled').change ->
+ if ($(this).is(':checked') == true)
+ $('#project_issues_tracker').removeAttr('disabled')
+ else
+ $('#project_issues_tracker').attr('disabled', 'disabled')
+
+ $('#project_issues_tracker').change()
+
+ $('#project_issues_tracker').change ->
+ if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled'))
+ $('#project_issues_tracker_id').attr('disabled', 'disabled')
+ else
+ $('#project_issues_tracker_id').removeAttr('disabled')
+
+@Project = Project
+
+$ ->
+ # Git clone panel switcher
+ scope = $ '.project_clone_holder'
+ if scope.length > 0
+ $('a, button', scope).click ->
+ $('a, button', scope).removeClass 'active'
+ $(@).addClass 'active'
+ $('#project_clone', scope).val $(@).data 'clone'
+
+ # Ref switcher
+ $('.project-refs-select').on 'change', ->
+ $(@).parents('form').submit()
diff --git a/app/assets/javascripts/projects.js.coffee b/app/assets/javascripts/projects.js.coffee
deleted file mode 100644
index 24106c61b75..00000000000
--- a/app/assets/javascripts/projects.js.coffee
+++ /dev/null
@@ -1,35 +0,0 @@
-window.Projects = ->
- $('.new_project, .edit_project').on 'ajax:before', ->
- $('.project_new_holder, .project_edit_holder').hide()
- $('.save-project-loader').show()
-
- $('form #project_default_branch').chosen()
- disableButtonIfEmptyField '#project_name', '.project-submit'
-
-$ ->
- # Git clone panel switcher
- scope = $ '.project_clone_holder'
- if scope.length > 0
- $('a, button', scope).click ->
- $('a, button', scope).removeClass 'active'
- $(@).addClass 'active'
- $('#project_clone', scope).val $(@).data 'clone'
-
- # Ref switcher
- $('.project-refs-select').on 'change', ->
- $(@).parents('form').submit()
-
- $('#project_issues_enabled').change ->
- if ($(this).is(':checked') == true)
- $('#project_issues_tracker').removeAttr('disabled')
- else
- $('#project_issues_tracker').attr('disabled', 'disabled')
-
- $('#project_issues_tracker').change()
-
- $('#project_issues_tracker').change ->
- if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled'))
- $('#project_issues_tracker_id').attr('disabled', 'disabled')
- else
- $('#project_issues_tracker_id').removeAttr('disabled')
-
diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee
new file mode 100644
index 00000000000..3418690e109
--- /dev/null
+++ b/app/assets/javascripts/search_autocomplete.js.coffee
@@ -0,0 +1,8 @@
+class SearchAutocomplete
+ constructor: (json) ->
+ $("#search").autocomplete
+ source: json
+ select: (event, ui) ->
+ location.href = ui.item.url
+
+@SearchAutocomplete = SearchAutocomplete
diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee
index 10d0df700e1..fdc82ff6668 100644
--- a/app/assets/javascripts/tree.js.coffee
+++ b/app/assets/javascripts/tree.js.coffee
@@ -1,40 +1,13 @@
# Code browser tree slider
+# Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
+$(".tree-content-holder .tree-item").live 'click', (e) ->
+ if (e.target.nodeName != "A")
+ path = $('.tree-item-file-name a', this).attr('href')
+ Turbolinks.visit(path)
$ ->
- if $('#tree-slider').length > 0
- # Show the "Loading commit data" for only the first element
- $('span.log_loading:first').removeClass('hide')
-
- $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live "click", ->
- $("#tree-content-holder").hide("slide", { direction: "left" }, 400)
-
- # Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
- $("#tree-slider .tree-item").live 'click', (e) ->
- $('.tree-item-file-name a', this).trigger('click') if (e.target.nodeName != "A")
-
- # Maintain forward/back history while browsing the file tree
- ((window) ->
- History = window.History
- $ = window.jQuery
- document = window.document
-
- # Check to see if History.js is enabled for our Browser
- unless History.enabled
- return false
-
- $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) ->
- History.pushState(null, null, decodeURIComponent($(@).attr('href')))
- return false
-
- History.Adapter.bind window, 'statechange', ->
- state = History.getState()
- $.ajax({
- url: state.url,
- dataType: 'script',
- beforeSend: -> $('.tree_progress').addClass("loading"),
- complete: -> $('.tree_progress').removeClass("loading")
- })
- )(window)
+ # Show the "Loading commit data" for only the first element
+ $('span.log_loading:first').removeClass('hide')
# See if there are lines selected
# "#L12" and "#L34-56" supported
diff --git a/app/assets/javascripts/wall.js.coffee b/app/assets/javascripts/wall.js.coffee
index e2fca3ddee4..c8fc960e174 100644
--- a/app/assets/javascripts/wall.js.coffee
+++ b/app/assets/javascripts/wall.js.coffee
@@ -1,32 +1,32 @@
-@Wall =
- note_ids: []
- project_id: null
-
- init: (project_id) ->
- Wall.project_id = project_id
- Wall.getContent()
- Wall.initRefresh()
- Wall.initForm()
+class Wall
+ constructor: (project_id) ->
+ @project_id = project_id
+ @note_ids = []
+ @getContent()
+ @initRefresh()
+ @initForm()
#
# Gets an initial set of notes.
#
getContent: ->
- Api.notes Wall.project_id, (notes) ->
- $.each notes, (i, note) ->
+ Api.notes @project_id, (notes) =>
+ $.each notes, (i, note) =>
# render note if it not present in loaded list
# or skip if rendered
- if $.inArray(note.id, Wall.note_ids) == -1
- Wall.note_ids.push(note.id)
- Wall.renderNote(note)
- Wall.scrollDown()
+ if $.inArray(note.id, @note_ids) == -1
+ @note_ids.push(note.id)
+ @renderNote(note)
+ @scrollDown()
$("abbr.timeago").timeago()
initRefresh: ->
- setInterval("Wall.refresh()", 10000)
+ setInterval =>
+ @refresh()
+ , 10000
refresh: ->
- Wall.getContent()
+ @getContent()
scrollDown: ->
notes = $('ul.notes')
@@ -36,8 +36,8 @@
form = $('.wall-note-form')
form.find("#target_type").val('wall')
- form.on 'ajax:success', ->
- Wall.refresh()
+ form.on 'ajax:success', =>
+ @refresh()
form.find(".js-note-text").val("").trigger("input")
form.on 'ajax:complete', ->
@@ -58,7 +58,7 @@
form.show()
renderNote: (note) ->
- template = Wall.noteTemplate()
+ template = @noteTemplate()
template = template.replace('{{author_name}}', note.author.name)
template = template.replace('{{created_at}}', note.created_at)
template = template.replace('{{text}}', linkify(sanitize(note.body)))
@@ -81,3 +81,5 @@
</span>
<abbr class="timeago" title="{{created_at}}">{{created_at}}</abbr>
</li>'
+
+@Wall = Wall
diff --git a/app/assets/javascripts/wikis.js.coffee b/app/assets/javascripts/wikis.js.coffee
new file mode 100644
index 00000000000..f2867c8026e
--- /dev/null
+++ b/app/assets/javascripts/wikis.js.coffee
@@ -0,0 +1,19 @@
+class Wikis
+ constructor: ->
+ modal = $('#modal-new-wiki').modal({modal: true, show:false})
+
+ $('.add-new-wiki').bind "click", ->
+ modal.show()
+
+ $('.build-new-wiki').bind "click", ->
+ field = $('#new_wiki_path')
+ slug = field.val()
+ path = field.attr('data-wikis-path')
+
+ if(slug.length > 0)
+ location.href = path + "/" + slug
+
+ $('.modal-header .close').bind "click", ->
+ modal.hide()
+
+@Wikis = Wikis
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 893cb2196d7..85e43ed0d35 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -41,6 +41,7 @@
@import "highlight/white.scss";
@import "highlight/dark.scss";
@import "highlight/solarized_dark.scss";
+@import "highlight/monokai.scss";
/**
* UI themes:
diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss
index c3cc601f16f..ccc6f7a9d2d 100644
--- a/app/assets/stylesheets/common.scss
+++ b/app/assets/stylesheets/common.scss
@@ -195,6 +195,11 @@ p.time {
top: -5px;
@include border-radius(4px);
+ &.success {
+ background: #4A4;
+ color: #FFF;
+ }
+
&.error {
background: #DA4E49;
color: #FFF;
diff --git a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
index 842e7a08057..867920ad08f 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/blocks.scss
@@ -13,6 +13,7 @@
background: #F9F9F9;
margin-bottom: 25px;
border: 1px solid #CCC;
+ word-wrap: break-word;
@include solid-shade;
&.ui-box-show {
@@ -41,7 +42,6 @@
.ui-box-body,
.ui-box-bottom {
padding: 15px;
- word-wrap: break-word;
.clearfix {
margin: 0;
@@ -171,3 +171,8 @@
margin: 3px 3px 25px 3px;
}
}
+
+.light-well {
+ background: #f9f9f9;
+ padding: 15px;
+}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
index 03497e32d26..e9b85686fad 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss
@@ -23,7 +23,7 @@
&.disabled {
color: #fff;
- background: #29B;
+ background: $primary_color;
}
}
@@ -39,7 +39,7 @@
&.disabled {
color: #fff;
- background: #29B;
+ background: $primary_color;
}
}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss
index 3ec03b96434..dd072b978d4 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/common.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss
@@ -74,3 +74,9 @@ fieldset legend { font-size: 17px; }
.tab-content {
overflow: visible;
}
+
+@media (max-width: 1200px) {
+ .only-wide {
+ display: none;
+ }
+}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
index 0f893a553ee..e661e02623e 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss
@@ -69,5 +69,14 @@ ul.bordered-list {
display: block;
margin: 0px;
&:last-child { border:none }
+
+ &.active {
+ background: #f9f9f9;
+ a { font-weight: bold; }
+ }
+
+ &.light {
+ a { color: #777; }
+ }
}
}
diff --git a/app/assets/stylesheets/gitlab_bootstrap/nav.scss b/app/assets/stylesheets/gitlab_bootstrap/nav.scss
index 2eaef61ca33..0fc8b21de7b 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/nav.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/nav.scss
@@ -16,7 +16,7 @@
padding: 12px;
}
> .active > a {
- border-color: #29B;
+ border-color: $primary_color;
border-radius: 0;
background: #F1F1F1;
color: $style_color;
diff --git a/app/assets/stylesheets/highlight/monokai.scss b/app/assets/stylesheets/highlight/monokai.scss
new file mode 100644
index 00000000000..c196cc1d61c
--- /dev/null
+++ b/app/assets/stylesheets/highlight/monokai.scss
@@ -0,0 +1,86 @@
+$monokai-fg: #f8f8f2;
+$monokai-comment: #75715e;
+$monokai-pink: #f92672;
+$monokai-blue: #66d9ef;
+$monokai-green: #a6e22e;
+$monokai-gold: #e6db74;
+$monokai-dark: #3b3a32;
+$monokai-purple: #ae81ff;
+
+.monokai .highlight {
+ pre {
+ background-color: #272822;
+ color: $monokai-fg;
+ }
+
+ .hll { background-color: #ffffcc }
+ .c { color: $monokai-comment } /* Comment */
+ .err { color: $monokai-fg } /* Error */
+ .g { color: $monokai-fg } /* Generic */
+ .k { color: $monokai-pink } /* Keyword */
+ .l { color: $monokai-fg } /* Literal */
+ .n { color: $monokai-blue } /* Name */
+ .o { color: $monokai-fg } /* Operator */
+ .x { color: $monokai-fg } /* Other */
+ .p { color: $monokai-fg } /* Punctuation */
+ .cm { color: $monokai-comment } /* Comment.Multiline */
+ .cp { color: $monokai-comment } /* Comment.Preproc */
+ .c1 { color: $monokai-comment } /* Comment.Single */
+ .cs { color: $monokai-comment } /* Comment.Special */
+ .gd { color: #8b0807 } /* Generic.Deleted */
+ .ge { color: $monokai-fg; text-decoration: underline } /* Generic.Emph */
+ .gr { color: $monokai-fg } /* Generic.Error */
+ .gh { color: $monokai-fg; font-weight: bold } /* Generic.Heading */
+ .gi { color: $monokai-fg; font-weight: bold; background-color: #46830c } /* Generic.Inserted */
+ .go { color: $monokai-dark; background-color: #31322c } /* Generic.Output */
+ .gp { color: $monokai-fg } /* Generic.Prompt */
+ .gs { color: $monokai-fg } /* Generic.Strong */
+ .gu { color: $monokai-fg; font-weight: bold } /* Generic.Subheading */
+ .gt { color: #f8f8f0; background-color: $monokai-pink } /* Generic.Traceback */
+ .kc { color: $monokai-purple } /* Keyword.Constant */
+ .kd { color: $monokai-pink } /* Keyword.Declaration */
+ .kn { color: $monokai-pink } /* Keyword.Namespace */
+ .kp { color: $monokai-pink } /* Keyword.Pseudo */
+ .kr { color: $monokai-pink } /* Keyword.Reserved */
+ .kt { color: $monokai-fg } /* Keyword.Type */
+ .ld { color: $monokai-fg } /* Literal.Date */
+ .m { color: $monokai-purple } /* Literal.Number */
+ .s { color: $monokai-gold } /* Literal.String */
+ .na { color: $monokai-purple } /* Name.Attribute */
+ .nb { color: $monokai-blue } /* Name.Builtin */
+ .nc { color: $monokai-fg } /* Name.Class */
+ .no { color: $monokai-fg } /* Name.Constant */
+ .nd { color: $monokai-fg } /* Name.Decorator */
+ .ni { color: $monokai-fg } /* Name.Entity */
+ .ne { color: $monokai-fg } /* Name.Exception */
+ .nf { color: $monokai-green } /* Name.Function */
+ .nl { color: $monokai-gold } /* Name.Label */
+ .nn { color: $monokai-fg } /* Name.Namespace */
+ .nx { color: $monokai-fg } /* Name.Other */
+ .nt { color: $monokai-pink } /* Name.Tag */
+ .nv { color: $monokai-blue; font-style: italic } /* Name.Variable */
+ .py { color: $monokai-fg } /* Name.Property */
+ .ow { color: $monokai-pink } /* Operator.Word */
+ .w { color: $monokai-fg } /* Text.Whitespace */
+ .mf { color: $monokai-purple } /* Literal.Number.Float */
+ .mh { color: $monokai-purple } /* Literal.Number.Hex */
+ .mi { color: $monokai-purple } /* Literal.Number.Integer */
+ .mo { color: $monokai-purple } /* Literal.Number.Oct */
+ .sb { color: $monokai-gold } /* Literal.String.Backtick */
+ .sc { color: $monokai-gold } /* Literal.String.Char */
+ .sd { color: $monokai-gold } /* Literal.String.Doc */
+ .s2 { color: $monokai-gold } /* Literal.String.Double */
+ .se { color: $monokai-gold } /* Literal.String.Escape */
+ .sh { color: $monokai-gold } /* Literal.String.Heredoc */
+ .si { color: $monokai-gold } /* Literal.String.Interpol */
+ .sx { color: $monokai-gold } /* Literal.String.Other */
+ .sr { color: $monokai-gold } /* Literal.String.Regex */
+ .s1 { color: $monokai-gold } /* Literal.String.Single */
+ .ss { color: $monokai-gold } /* Literal.String.Symbol */
+ .bp { color: $monokai-fg } /* Name.Builtin.Pseudo */
+ .vc { color: $monokai-blue; font-style: italic } /* Name.Variable.Class */
+ .vg { color: $monokai-blue; font-style: italic } /* Name.Variable.Global */
+ .vi { color: $monokai-blue; font-style: italic } /* Name.Variable.Instance */
+ .il { color: $monokai-purple } /* Literal.Number.Integer.Long */
+}
+
diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss
index 51a307e4d4e..812587a2ee6 100644
--- a/app/assets/stylesheets/sections/commits.scss
+++ b/app/assets/stylesheets/sections/commits.scss
@@ -99,12 +99,24 @@
}
}
}
+ .line_holder {
+ &.old .old_line,
+ &.old .new_line {
+ background: #FCC;
+ border-color: #E7BABA;
+ }
+ &.new .old_line,
+ &.new .new_line {
+ background: #CFC;
+ border-color: #B9ECB9;
+ }
+ }
.line_content {
display: block;
white-space: pre;
height: 18px;
margin: 0px;
- padding: 0px;
+ padding: 0px 0.5em;
border: none;
&.new {
background: #CFD;
diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss
index 4876af296d8..40f35b65da6 100644
--- a/app/assets/stylesheets/sections/events.scss
+++ b/app/assets/stylesheets/sections/events.scss
@@ -124,7 +124,7 @@
color: #777;
padding: 10px;
min-height: 22px;
- border-left: 5px solid #5AB9C3;
+ border-left: 5px solid $primary_color;
margin-bottom: 20px;
background: #f9f9f9;
@@ -133,10 +133,10 @@
}
.btn-new-mr {
- @extend .btn-info;
+ @extend .btn-primary;
@extend .small;
@extend .pull-right;
- margin: -3px;
+ margin: -2px;
}
}
@@ -152,7 +152,7 @@
.filter_icon {
a {
text-align:center;
- border-left: 3px solid #29B;
+ border-left: 3px solid $primary_color;
background: #f9f9f9;
margin-bottom: 10px;
float: left;
diff --git a/app/assets/stylesheets/sections/graph.scss b/app/assets/stylesheets/sections/graph.scss
index 7da00719b33..58c2c203219 100644
--- a/app/assets/stylesheets/sections/graph.scss
+++ b/app/assets/stylesheets/sections/graph.scss
@@ -13,7 +13,8 @@
background: #f1f1f1;
cursor: move;
height: 500px;
- overflow: hidden;
+ overflow-y: scroll;
+ overflow-x: hidden;
}
}
diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss
index a8628fc58f2..a86384dc2ef 100644
--- a/app/assets/stylesheets/sections/notes.scss
+++ b/app/assets/stylesheets/sections/notes.scss
@@ -213,7 +213,17 @@ ul.notes {
.reply-btn {
@extend .btn-primary;
}
-.file .content tr.line_holder:hover > td { background: $hover !important; }
+.file .content tr.line_holder:hover {
+ &> td.line_content {
+ background: $hover !important;
+ border-color: darken($hover, 10%) !important;
+ }
+ &> td.new_line,
+ &> td.old_line {
+ background: darken($hover, 4%) !important;
+ border-color: darken($hover, 10%) !important;
+ }
+}
.file .content tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
filter: alpha(opacity=100);
diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss
index 6c890d3420d..22618765eaa 100644
--- a/app/assets/stylesheets/sections/projects.scss
+++ b/app/assets/stylesheets/sections/projects.scss
@@ -33,14 +33,6 @@
}
.project_clone_holder {
- input[type="text"],
- .btn {
- font-size: 12px;
- line-height: 18px;
- margin: 0;
- padding: 3px 10px;
- }
-
input[type="text"] {
@extend .monospace;
border: 1px solid #BBB;
diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss
index def440c7134..ffde6aa3fa6 100644
--- a/app/assets/stylesheets/sections/tree.scss
+++ b/app/assets/stylesheets/sections/tree.scss
@@ -97,7 +97,7 @@
.tree-btn-group {
.btn {
- margin-right:-3px;
+ margin-right: 0px;
padding: 2px 10px;
}
}
diff --git a/app/contexts/projects/create_context.rb b/app/contexts/projects/create_context.rb
index 56c4e1c51da..2922564ba20 100644
--- a/app/contexts/projects/create_context.rb
+++ b/app/contexts/projects/create_context.rb
@@ -8,7 +8,18 @@ module Projects
# get namespace id
namespace_id = params.delete(:namespace_id)
- @project = Project.new(params)
+ # Load default feature settings
+ default_features = Gitlab.config.gitlab.default_projects_features
+
+ default_opts = {
+ issues_enabled: default_features.issues,
+ wiki_enabled: default_features.wiki,
+ wall_enabled: default_features.wall,
+ snippets_enabled: default_features.snippets,
+ merge_requests_enabled: default_features.merge_requests
+ }
+
+ @project = Project.new(default_opts.merge(params))
# Parametrize path for project
#
@@ -32,10 +43,6 @@ module Projects
@project.namespace_id = current_user.namespace_id
end
- # Disable less important features by default
- @project.wall_enabled = false
- @project.snippets_enabled = false
-
@project.creator = current_user
# Import project from cloneable resource
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 32b1246601d..22fe5abacb3 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -155,5 +155,6 @@ class ApplicationController < ActionController::Base
gon.api_version = Gitlab::API.version
gon.api_token = current_user.private_token if current_user
gon.gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
+ gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
end
end
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 91a67985710..f651b02c1e5 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -34,6 +34,7 @@ class DashboardController < ApplicationController
@projects
end
+ @projects = @projects.tagged_with(params[:label]) if params[:label].present?
@projects = @projects.search(params[:search]) if params[:search].present?
@projects = @projects.page(params[:page]).per(30)
end
diff --git a/app/controllers/edit_tree_controller.rb b/app/controllers/edit_tree_controller.rb
index e3bd10ec758..9ed7a2143e4 100644
--- a/app/controllers/edit_tree_controller.rb
+++ b/app/controllers/edit_tree_controller.rb
@@ -25,7 +25,7 @@ class EditTreeController < ProjectResourceController
redirect_to project_blob_path(@project, @id), notice: "Your changes have been successfully commited"
else
flash[:notice] = "Your changes could not be commited, because the file has been changed"
- render :edit
+ render :show
end
end
diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb
index 135281bd28d..25647f97576 100644
--- a/app/controllers/milestones_controller.rb
+++ b/app/controllers/milestones_controller.rb
@@ -14,7 +14,7 @@ class MilestonesController < ProjectResourceController
@milestones = case params[:f]
when 'all'; @project.milestones.order("state, due_date DESC")
when 'closed'; @project.milestones.closed.order("due_date DESC")
- else @project.milestones.active.order("due_date ASC")
+ else @project.milestones.active.order("due_date DESC")
end
@milestones = @milestones.includes(:project)
@@ -32,7 +32,7 @@ class MilestonesController < ProjectResourceController
def show
@issues = @milestone.issues
- @users = @milestone.participants
+ @users = @milestone.participants.uniq
@merge_requests = @milestone.merge_requests
respond_to do |format|
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index e116bc358c9..188feb73ec1 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -13,6 +13,8 @@ class RefsController < ProjectResourceController
format.html do
new_path = if params[:destination] == "tree"
project_tree_path(@project, (@ref + "/" + params[:path]))
+ elsif params[:destination] == "blob"
+ project_blob_path(@project, (@ref + "/" + params[:path]))
elsif params[:destination] == "graph"
project_graph_path(@project, @ref)
else
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 6fba2518306..a7d393af82b 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -27,7 +27,9 @@ class RepositoriesController < ProjectResourceController
end
- file_path = @repository.archive_repo(params[:ref])
+ storage_path = Rails.root.join("tmp", "repositories")
+
+ file_path = @repository.archive_repo(params[:ref], storage_path)
if file_path
# Send file to user
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 387172b5804..703c88975a3 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -37,7 +37,7 @@ module ApplicationHelper
if !Gitlab.config.gravatar.enabled || user_email.blank?
'no_avatar.png'
else
- gravatar_url = request.ssl? ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
+ gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
user_email.strip!
sprintf gravatar_url, hash: Digest::MD5.hexdigest(user_email.downcase), size: size
end
@@ -132,18 +132,27 @@ module ApplicationHelper
when 1 then 'white'
when 2 then 'black'
when 3 then 'solarized-dark'
+ when 4 then 'monokai'
else
'white'
end
end
+ # Define whenever show last push event
+ # with suggestion to create MR
def show_last_push_widget?(event)
- event &&
- event.last_push_to_non_root? &&
- !event.rm_ref? &&
- event.project &&
- event.project.repository &&
- event.project.merge_requests_enabled
+ # Skip if event is not about added or modified non-master branch
+ return false unless event && event.last_push_to_non_root? && !event.rm_ref?
+
+ project = event.project
+
+ # Skip if project repo is empty or MR disabled
+ return false unless project && !project.empty_repo? && project.merge_requests_enabled
+
+ # Skip if user already created appropriate MR
+ return false if project.merge_requests.where(source_branch: event.branch_name).opened.any?
+
+ true
end
def hexdigest(string)
@@ -180,4 +189,11 @@ module ApplicationHelper
css_class << " multiselect" if opts[:multiple]
hidden_field_tag(id, '', class: css_class)
end
+
+ def body_data_page
+ path = controller.controller_path.split('/')
+ namespace = path.first if path.second
+
+ [namespace, controller.controller_name, controller.action_name].compact.join(":")
+ end
end
diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb
index ca7d823a45a..71a07d6cad1 100644
--- a/app/helpers/graph_helper.rb
+++ b/app/helpers/graph_helper.rb
@@ -4,8 +4,7 @@ module GraphHelper
refs += commit.refs.collect{|r|r.name}.join(" ") if commit.refs
# append note count
- notes = @project.notes.for_commit_id(commit.id)
- refs += "[#{notes.count}]" if notes.any?
+ refs += "[#{@graph.notes[commit.id]}]" if @graph.notes[commit.id] > 0
refs
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 1db8b7c689c..9e7c4ee245a 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -3,6 +3,10 @@ module ProjectsHelper
"You are going to remove #{user.name} from #{project.name} project team. Are you sure?"
end
+ def projects_labels
+ Project.tag_counts_on(:labels).map(&:name)
+ end
+
def link_to_project project
link_to project do
title = content_tag(:strong, project.name)
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index e7002f60b8a..1f764ea1038 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -5,24 +5,18 @@ module TreeHelper
# contents - A Grit::Tree object for the current tree
def render_tree(tree)
# Render Folders before Files/Submodules
- folders, files = tree.trees, tree.blobs
+ folders, files, submodules = tree.trees, tree.blobs, tree.submodules
tree = ""
# Render folders if we have any
tree += render partial: 'tree/tree_item', collection: folders, locals: {type: 'folder'} if folders.present?
- files.each do |f|
- html = if f.respond_to?(:url)
- # Object is a Submodule
- render partial: 'tree/submodule_item', object: f
- else
- # Object is a Blob
- render partial: 'tree/blob_item', object: f, locals: {type: 'file'}
- end
+ # Render files if we have any
+ tree += render partial: 'tree/blob_item', collection: files, locals: {type: 'file'} if files.present?
- tree += html if html.present?
- end
+ # Render submodules if we have any
+ tree += render partial: 'tree/submodule_item', collection: submodules if submodules.present?
tree.html_safe
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 105d9239cf6..c1b4d4e0760 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -24,8 +24,6 @@ require Rails.root.join("lib/static_model")
class MergeRequest < ActiveRecord::Base
include Issuable
- BROKEN_DIFF = "--broken-diff"
-
attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id,
:author_id_of_changes, :state_event
@@ -109,22 +107,18 @@ class MergeRequest < ActiveRecord::Base
end
def diffs
- st_diffs || []
+ load_diffs(st_diffs) || []
end
def reloaded_diffs
if opened? && unmerged_diffs.any?
- self.st_diffs = unmerged_diffs
+ self.st_diffs = dump_diffs(unmerged_diffs)
self.save
end
-
- rescue Grit::Git::GitTimeout
- self.st_diffs = [BROKEN_DIFF]
- self.save
end
def broken_diffs?
- diffs == [BROKEN_DIFF]
+ diffs == [Gitlab::Git::Diff::BROKEN_DIFF]
end
def valid_diffs?
@@ -132,11 +126,7 @@ class MergeRequest < ActiveRecord::Base
end
def unmerged_diffs
- # Only show what is new in the source branch compared to the target branch, not the other way around.
- # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
- # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
- common_commit = project.repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
- diffs = project.repo.diff(common_commit, source_branch)
+ project.repository.diffs_between(source_branch, target_branch)
end
def last_commit
@@ -222,4 +212,12 @@ class MergeRequest < ActiveRecord::Base
def load_commits(array)
array.map { |hash| Commit.new(Gitlab::Git::Commit.new(hash)) }
end
+
+ def dump_diffs(diffs)
+ diffs.map(&:to_hash)
+ end
+
+ def load_diffs(array)
+ array.map { |hash| Gitlab::Git::Diff.new(hash) }
+ end
end
diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb
index 0fe7765b9ea..27072836cbb 100644
--- a/app/models/network/graph.rb
+++ b/app/models/network/graph.rb
@@ -2,7 +2,7 @@ require "grit"
module Network
class Graph
- attr_reader :days, :commits, :map
+ attr_reader :days, :commits, :map, :notes
def self.max_count
@max_count ||= 650
@@ -16,10 +16,19 @@ module Network
@commits = collect_commits
@days = index_commits
+ @notes = collect_notes
end
protected
+ def collect_notes
+ h = Hash.new(0)
+ @project.notes.where('noteable_type = ?' ,"Commit").group('notes.commit_id').select('notes.commit_id, count(notes.id) as note_count').each do |item|
+ h[item["commit_id"]] = item["note_count"]
+ end
+ h
+ end
+
# Get commits from repository
#
def collect_commits
@@ -181,7 +190,7 @@ module Network
l.spaces << space
# Also add space to parent
l.parents(@map).each do |parent|
- if parent.space > 0
+ if 0 < parent.space && parent.space < space
parent.spaces << space
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 8274b866568..7b7e6e99df4 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -68,8 +68,8 @@ class Note < ActiveRecord::Base
def diff
if noteable.diffs.present?
noteable.diffs.select do |d|
- if d.b_path
- Digest::SHA1.hexdigest(d.b_path) == diff_file_index
+ if d.new_path
+ Digest::SHA1.hexdigest(d.new_path) == diff_file_index
end
end.first
end
@@ -80,7 +80,7 @@ class Note < ActiveRecord::Base
end
def diff_file_name
- diff.b_path
+ diff.new_path
end
def diff_new_line
diff --git a/app/models/project.rb b/app/models/project.rb
index 1d1b7c1134c..291316f3088 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -28,12 +28,14 @@ class Project < ActiveRecord::Base
include Gitlab::ShellAdapter
extend Enumerize
- attr_accessible :name, :path, :description, :default_branch, :issues_tracker,
+ attr_accessible :name, :path, :description, :default_branch, :issues_tracker, :label_list,
:issues_enabled, :wall_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
:wiki_enabled, :public, :import_url, :last_activity_at, as: [:default, :admin]
attr_accessible :namespace_id, :creator_id, as: :admin
+ acts_as_taggable_on :labels
+
attr_accessor :import_url
# Relations
diff --git a/app/models/repository.rb b/app/models/repository.rb
index ed600e29232..d45ec9bd575 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -37,6 +37,22 @@ class Repository
raw_repository.send(m, *args, &block)
end
+ # Return repo size in megabytes
+ # Cached in redis
+ def size
+ Rails.cache.fetch(cache_key(:size)) do
+ raw_repository.size
+ end
+ end
+
+ def expire_cache
+ Rails.cache.delete(cache_key(:size))
+ end
+
+ def cache_key(type)
+ "#{type}:#{path_with_namespace}"
+ end
+
def respond_to?(method)
return true if raw_repository.respond_to?(method)
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 4b3c982c189..379d2c54629 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -13,7 +13,7 @@ class NotificationService
# even if user disabled notifications
def new_key(key)
if key.user
- Notify.delay.new_ssh_key_email(key.id)
+ mailer.new_ssh_key_email(key.id)
end
end
@@ -84,14 +84,14 @@ class NotificationService
recipients = recipients.concat(project_watchers(merge_request.project)).uniq
recipients.each do |recipient|
- Notify.delay.merged_merge_request_email(recipient.id, merge_request.id)
+ mailer.merged_merge_request_email(recipient.id, merge_request.id)
end
end
# Notify new user with email after creation
def new_user(user)
# Dont email omniauth created users
- Notify.delay.new_user_email(user.id, user.password) unless user.extern_uid?
+ mailer.new_user_email(user.id, user.password) unless user.extern_uid?
end
# Notify users on new note in system
@@ -131,16 +131,16 @@ class NotificationService
notify_method = "note_#{note.noteable_type.underscore}_email".to_sym
recipients.each do |recipient|
- Notify.delay.send(notify_method, recipient.id, note.id)
+ mailer.send(notify_method, recipient.id, note.id)
end
end
def new_team_member(users_project)
- Notify.delay.project_access_granted_email(users_project.id)
+ mailer.project_access_granted_email(users_project.id)
end
def update_team_member(users_project)
- Notify.delay.project_access_granted_email(users_project.id)
+ mailer.project_access_granted_email(users_project.id)
end
protected
@@ -186,7 +186,7 @@ class NotificationService
recipients.delete(target.author)
recipients.each do |recipient|
- Notify.delay.send(method, recipient.id, target.id)
+ mailer.send(method, recipient.id, target.id)
end
end
@@ -196,7 +196,7 @@ class NotificationService
recipients.delete(current_user)
recipients.each do |recipient|
- Notify.delay.send(method, recipient.id, target.id, current_user.id)
+ mailer.send(method, recipient.id, target.id, current_user.id)
end
end
@@ -213,7 +213,11 @@ class NotificationService
recipients.delete(current_user)
recipients.each do |recipient|
- Notify.delay.send(method, recipient.id, target.id, target.assignee_id_was)
+ mailer.send(method, recipient.id, target.id, target.assignee_id_was)
end
end
+
+ def mailer
+ Notify.delay
+ end
end
diff --git a/app/views/admin/groups/edit.html.haml b/app/views/admin/groups/edit.html.haml
index bb1398f66cd..af87503128e 100644
--- a/app/views/admin/groups/edit.html.haml
+++ b/app/views/admin/groups/edit.html.haml
@@ -27,5 +27,5 @@
%li It will change the git path to repositories under this group.
.form-actions
- = f.submit 'Edit group', class: "btn btn-remove"
+ = f.submit 'Save changes', class: "btn btn-primary"
= link_to 'Cancel', admin_groups_path, class: "btn btn-cancel"
diff --git a/app/views/admin/groups/new.html.haml b/app/views/admin/groups/new.html.haml
index 6f76ee648ae..2da654ec764 100644
--- a/app/views/admin/groups/new.html.haml
+++ b/app/views/admin/groups/new.html.haml
@@ -15,7 +15,7 @@
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
.form-actions
- = f.submit 'Create group', class: "btn btn-primary"
+ = f.submit 'Create group', class: "btn btn-create"
%hr
.padded
diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml
index 63ea78fdd99..0e2e144d326 100644
--- a/app/views/admin/groups/show.html.haml
+++ b/app/views/admin/groups/show.html.haml
@@ -94,7 +94,7 @@
%td= select_tag :project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3"}
%tr
- %td= submit_tag 'Add user to projects in group', class: "btn btn-primary"
+ %td= submit_tag 'Add user to projects in group', class: "btn btn-create"
%td
Read more about project permissions
%strong= link_to "here", help_permissions_path, class: "vlink"
@@ -116,18 +116,5 @@
.input
= select_tag :project_ids, options_from_collection_for_select(@projects , :id, :name_with_namespace), multiple: true, data: {placeholder: 'Select projects'}, class: 'chosen span5'
.form-actions
- = submit_tag 'Add', class: "btn btn-primary"
-
-:javascript
- $(function(){
- var modal = $('.change-owner-holder');
- $('.change-owner-link').bind("click", function(){
- $(this).hide();
- modal.show();
- });
- $('.change-owner-cancel-link').bind("click", function(){
- modal.hide();
- $('.change-owner-link').show();
- })
- })
+ = submit_tag 'Move projects', class: "btn btn-create"
diff --git a/app/views/admin/hooks/index.html.haml b/app/views/admin/hooks/index.html.haml
index acbf7a108b8..316e8235cbe 100644
--- a/app/views/admin/hooks/index.html.haml
+++ b/app/views/admin/hooks/index.html.haml
@@ -15,7 +15,7 @@
.input
= f.text_field :url, class: "text_field xxlarge"
&nbsp;
- = f.submit "Add System Hook", class: "btn btn-primary"
+ = f.submit "Add System Hook", class: "btn btn-create"
%hr
-if @hooks.any?
diff --git a/app/views/admin/teams/index.html.haml b/app/views/admin/teams/index.html.haml
index 225ad166774..cf24ed5398f 100644
--- a/app/views/admin/teams/index.html.haml
+++ b/app/views/admin/teams/index.html.haml
@@ -1,7 +1,7 @@
%h3.page_title
Teams
%small
- simple Teams description
+ allow you to organize groups of people that have a common focus. Use teams to simplify the process of assigning roles to groups of people.
= link_to 'New Team', new_admin_team_path, class: "btn btn-small pull-right"
%br
diff --git a/app/views/admin/teams/new.html.haml b/app/views/admin/teams/new.html.haml
index 1c90cb20c10..8bccdacc351 100644
--- a/app/views/admin/teams/new.html.haml
+++ b/app/views/admin/teams/new.html.haml
@@ -16,7 +16,7 @@
= f.text_area :description, maxlength: 250, class: "xxlarge js-gfm-input", rows: 4
.form-actions
- = f.submit 'Create team', class: "btn btn-primary"
+ = f.submit 'Create team', class: "btn btn-create"
%hr
.padded
diff --git a/app/views/admin/teams/show.html.haml b/app/views/admin/teams/show.html.haml
index abdfada8c5e..bd4d90b607f 100644
--- a/app/views/admin/teams/show.html.haml
+++ b/app/views/admin/teams/show.html.haml
@@ -91,17 +91,3 @@
= link_to 'Edit', edit_admin_team_project_path(@team, project), class: "btn btn-small"
&nbsp;
= link_to 'Relegate', admin_team_project_path(@team, project), confirm: 'Remove project from team. Are you sure?', method: :delete, class: "btn btn-remove small", id: "relegate_project_#{project.id}"
-
-:javascript
- $(function(){
- var modal = $('.change-owner-holder');
- $('.change-owner-link').bind("click", function(){
- $(this).hide();
- modal.show();
- });
- $('.change-owner-cancel-link').bind("click", function(){
- modal.hide();
- $('.change-owner-link').show();
- })
- })
-
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 1d1fe341c5b..9bde50f8947 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -80,8 +80,9 @@
.input= f.text_field :twitter
.actions
- = f.submit 'Save', class: "btn btn-save"
- if @admin_user.new_record?
+ = f.submit 'Create user', class: "btn btn-create"
= link_to 'Cancel', admin_users_path, class: "btn btn-cancel"
- else
+ = f.submit 'Save changes', class: "btn btn-save"
= link_to 'Cancel', admin_user_path(@admin_user), class: "btn btn-cancel"
diff --git a/app/views/blob/_actions.html.haml b/app/views/blob/_actions.html.haml
index 1da39e72c98..456c7432c94 100644
--- a/app/views/blob/_actions.html.haml
+++ b/app/views/blob/_actions.html.haml
@@ -8,5 +8,5 @@
- if current_page? project_blame_path(@project, @id)
= link_to "normal view", project_blob_path(@project, @id), class: "btn btn-tiny"
- else
- = link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny"
+ = link_to "blame", project_blame_path(@project, @id), class: "btn btn-tiny" unless @blob.empty?
= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny"
diff --git a/app/views/blob/show.html.haml b/app/views/blob/show.html.haml
index d1ca0e05e83..d96595bc7f0 100644
--- a/app/views/blob/show.html.haml
+++ b/app/views/blob/show.html.haml
@@ -1,4 +1,4 @@
%div.tree-ref-holder
- = render 'shared/ref_switcher', destination: 'tree', path: @path
+ = render 'shared/ref_switcher', destination: 'blob', path: @path
%div#tree-holder.tree-holder
= render 'blob', blob: @blob
diff --git a/app/views/blob/show.js.haml b/app/views/blob/show.js.haml
deleted file mode 100644
index 804107f42fa..00000000000
--- a/app/views/blob/show.js.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-:plain
- // Load Files list
- $("#tree-holder").html("#{escape_javascript(render(partial: "blob", locals: {blob: @blob}))}");
- $("#tree-content-holder").show("slide", { direction: "right" }, 400);
- $('.project-refs-form #path').val("#{@path}");
-
- // Load last commit log for each file in tree
- $('#tree-slider').waitForImages(function() {
- ajaxGet('#{@logs_path}');
- });
diff --git a/app/views/commit/huge_commit.html.haml b/app/views/commit/huge_commit.html.haml
index 7f0bcf38037..5d447d6cee5 100644
--- a/app/views/commit/huge_commit.html.haml
+++ b/app/views/commit/huge_commit.html.haml
@@ -1,3 +1,3 @@
-= render "commits/commit_box"
+= render "commit/commit_box"
.alert.alert-error
%h4 Commit diffs are too big to be displayed
diff --git a/app/views/commit/show.html.haml b/app/views/commit/show.html.haml
index 48fb44a99d5..6cb1a6905ca 100644
--- a/app/views/commit/show.html.haml
+++ b/app/views/commit/show.html.haml
@@ -9,10 +9,3 @@
= render "commits/diffs", diffs: @commit.diffs
= render "notes/notes_with_form"
-
-:javascript
- $(function(){
- $('.files .file').each(function(){
- new CommitFile(this);
- });
- });
diff --git a/app/views/commits/_text_file.html.haml b/app/views/commits/_text_file.html.haml
index 760fd07ed8b..8f737e43887 100644
--- a/app/views/commits/_text_file.html.haml
+++ b/app/views/commits/_text_file.html.haml
@@ -4,7 +4,7 @@
%table.text-file{class: "#{'hide' if too_big}"}
- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old|
- %tr.line_holder{ id: line_code }
+ %tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match"
%td.old_line= "..."
%td.new_line= "..."
diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml
index 586b21dfa5d..cb9ef820d3e 100644
--- a/app/views/commits/show.html.haml
+++ b/app/views/commits/show.html.haml
@@ -11,7 +11,5 @@
- if @commits.count == @limit
:javascript
- $(function(){
- CommitsList.init("#{@ref}", #{@limit});
- });
+ CommitsList.init("#{@ref}", #{@limit});
diff --git a/app/views/dashboard/_sidebar.html.haml b/app/views/dashboard/_sidebar.html.haml
index 876a5b61297..748ff9810b5 100644
--- a/app/views/dashboard/_sidebar.html.haml
+++ b/app/views/dashboard/_sidebar.html.haml
@@ -22,7 +22,4 @@
News Feed
%hr
-.gitlab-promo
- = link_to "Homepage", "http://gitlab.org"
- = link_to "Blog", "http://blog.gitlab.org"
- = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
+= render 'shared/promo'
diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml
index f81af59b38f..511366cf1ab 100644
--- a/app/views/dashboard/projects.html.haml
+++ b/app/views/dashboard/projects.html.haml
@@ -20,6 +20,15 @@
= nav_tab :scope, 'joined' do
= link_to "Joined", projects_dashboard_path(scope: 'joined')
+ %p.light Filter by label:
+ %ul.bordered-list
+ - projects_labels.each do |label|
+ %li{ class: (label == params[:label]) ? 'active' : 'light' }
+ = link_to projects_dashboard_path(scope: params[:scope], label: label) do
+ %i.icon-tag
+ = label
+
+
.span9
= form_tag projects_dashboard_path, method: 'get' do
%fieldset.dashboard-search-filter
@@ -49,6 +58,10 @@
.left
- if project.description.present?
%span.light= project.description
+ - project.labels.each do |label|
+ %span.label.label-info
+ %i.icon-tag
+ = label.name
.pull-right.light
%small.light
diff --git a/app/views/dashboard/show.html.haml b/app/views/dashboard/show.html.haml
index ff2db0e3180..2305eae1f71 100644
--- a/app/views/dashboard/show.html.haml
+++ b/app/views/dashboard/show.html.haml
@@ -7,6 +7,3 @@
- else
= render "zero_authorized_projects"
-
-:javascript
- dashboardPage();
diff --git a/app/views/deploy_keys/index.html.haml b/app/views/deploy_keys/index.html.haml
index 66a8d3b7b7b..8fa9d5f3bca 100644
--- a/app/views/deploy_keys/index.html.haml
+++ b/app/views/deploy_keys/index.html.haml
@@ -1,7 +1,7 @@
= render "projects/settings_nav"
%p.slead
- Deploy keys allow read-only access to repository. They can be used for for CI, staging or production servers. A deploy key can be added to only one project. If you need to add the same key to multiple projects you can create a deploy user and add that user to multiple projects.
+ Deploy keys allow read-only access to repository. They can be used for CI, staging or production servers. A deploy key can be added to only one project. If you need to add the same key to multiple projects you can create a deploy user and add that user to multiple projects.
- if can? current_user, :admin_project, @project
= link_to new_project_deploy_key_path(@project), class: "btn btn-small", title: "New Deploy Key" do
diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml
index eb8c5194607..29ba9c1e99c 100644
--- a/app/views/devise/sessions/_new_ldap.html.haml
+++ b/app/views/devise/sessions/_new_ldap.html.haml
@@ -1,29 +1,29 @@
-= form_tag(user_omniauth_callback_path(:ldap), :class => "login-box", :id => 'new_ldap_user' ) do
- = image_tag "login-logo.png", :width => "304", :height => "66", :class => "login-logo", :alt => "Login Logo"
- = text_field_tag :username, nil, {:class => "text top", :placeholder => "LDAP Login", :autofocus => "autofocus"}
- = password_field_tag :password, nil, {:class => "text bottom", :placeholder => "Password"}
+= form_tag(user_omniauth_callback_path(:ldap), class: "login-box", id: 'new_ldap_user' ) do
+ = image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo"
+ = text_field_tag :username, nil, {class: "text top", placeholder: "LDAP Login", autofocus: "autofocus"}
+ = password_field_tag :password, nil, {class: "text bottom", placeholder: "Password"}
%br/
- = submit_tag "LDAP Sign in", :class => "btn-primary btn"
+ = submit_tag "LDAP Sign in", class: "btn-primary btn"
- if devise_mapping.omniauthable?
- (resource_class.omniauth_providers - [:ldap]).each do |provider|
%hr/
- = link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), :class => "btn btn-primary"
+ = link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), class: "btn btn-primary"
%br/
%hr/
- %a#other_form_toggle{:href => "#", :onclick => "javascript:$('#new_user').toggle();"} Other Sign in
+ %a#other_form_toggle{href: "#", onclick: "javascript:$('#new_user').toggle();"} Other Sign in
:javascript
$(function() {
$('#new_user').toggle();
});
-= form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => { :class => "login-box" }) do |f|
- = f.text_field :email, :class => "text top", :placeholder => "Email"
- = f.password_field :password, :class => "text bottom", :placeholder => "Password"
+= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "login-box" }) do |f|
+ = f.text_field :login, class: "text top", placeholder: "Username or Email", autofocus: "autofocus"
+ = f.password_field :password, class: "text bottom", placeholder: "Password"
- if devise_mapping.rememberable?
.clearfix.inputs-list
- %label.checkbox.remember_me{:for => "user_remember_me"}
+ %label.checkbox.remember_me{for: "user_remember_me"}
= f.check_box :remember_me
%span Remember me
%br/
- = f.submit "Sign in", :class => "btn-primary btn"
+ = f.submit "Sign in", class: "btn-primary btn"
.pull-right
- = render :partial => "devise/shared/links"
+ = render partial: "devise/shared/links"
diff --git a/app/views/graph/show.html.haml b/app/views/graph/show.html.haml
index e45aca1ddcb..682d2798906 100644
--- a/app/views/graph/show.html.haml
+++ b/app/views/graph/show.html.haml
@@ -7,11 +7,10 @@
:javascript
var branch_graph;
- $(function(){
- branch_graph = new BranchGraph($("#holder"), {
- url: '#{project_graph_path(@project, @ref, q: @q, format: :json)}',
- commit_url: '#{project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")}',
- ref: '#{@ref}',
- commit_id: '#{@commit.id}'
- });
+
+ branch_graph = new BranchGraph($("#holder"), {
+ url: '#{project_graph_path(@project, @ref, q: @q, format: :json)}',
+ commit_url: '#{project_commit_path(@project, 'ae45ca32').gsub("ae45ca32", "%s")}',
+ ref: '#{@ref}',
+ commit_id: '#{@commit.id}'
});
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index 62d640c8532..1ce008f7e85 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -23,10 +23,4 @@
News Feed
%hr
- .gitlab-promo
- = link_to "Homepage", "http://gitlabhq.com"
- = link_to "Blog", "http://blog.gitlabhq.com"
- = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
-
-:javascript
- $(function(){ Pager.init(20, true); });
+ = render 'shared/promo'
diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml
index 6d7613a700d..ae386961948 100644
--- a/app/views/issues/_form.html.haml
+++ b/app/views/issues/_form.html.haml
@@ -19,7 +19,7 @@
= f.label :assignee_id do
%i.icon-user
Assign to
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
+ .input= f.select(:assignee_id, @project.users.alphabetically.collect {|p| [ p.name, p.id ] }, { include_blank: "Select a user" }, {class: 'chosen'})
.issue_milestone.pull-left
= f.label :milestone_id do
%i.icon-time
diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml
index 4edc1d9b912..bf33769349a 100644
--- a/app/views/issues/index.html.haml
+++ b/app/views/issues/index.html.haml
@@ -4,7 +4,7 @@
Issues
%span (<span class=issue_counter>#{@issues.total_count}</span>)
.pull-right
- .span5
+ .span6
- if can? current_user, :write_issue, @project
= link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-primary pull-right", title: "New Issue", id: "new_issue_link" do
%i.icon-plus
@@ -23,8 +23,3 @@
= render 'filter', entity: 'issue'
.span9.issues-holder
= render "issues"
-
-:javascript
- $(function(){
- Issues.init();
- })
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 8f6873e1dfc..b43650459d8 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -9,6 +9,11 @@
%h1.project_name= title
%ul.nav
%li
+ %a
+ %div.hide.turbolink-spinner
+ %i.icon-refresh.icon-spin
+ Loading...
+ %li
= render "layouts/search"
%li
= link_to public_root_path, title: "Public area", class: 'has_bottom_tooltip', 'data-original-title' => 'Public area' do
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index c484af04704..16f52270902 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -3,11 +3,4 @@
= text_field_tag "search", nil, placeholder: "Search", class: "search-input"
= hidden_field_tag :group_id, @group.try(:id)
= hidden_field_tag :project_id, @project.try(:id)
-
-:javascript
- $(function(){
- $("#search").autocomplete({
- source: #{raw search_autocomplete_source},
- select: function(event, ui) { location.href = ui.item.url }
- });
- });
+ .search-autocomplete-json.hide{:'data-autocomplete-opts' => search_autocomplete_source }
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index abe3f2ea854..3a23cbdb376 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: "Admin area"
- %body{class: "#{app_theme} admin"}
+ %body{class: "#{app_theme} admin", :'data-page' => body_data_page}
= render "layouts/head_panel", title: "Admin area"
= render "layouts/flash"
%nav.main-nav
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 4e6831406e3..792fe5e4a28 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: "Dashboard"
- %body{class: "#{app_theme} application"}
+ %body{class: "#{app_theme} application", :'data-page' => body_data_page }
= render "layouts/head_panel", title: "Dashboard"
= render "layouts/flash"
%nav.main-nav
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 8296b8ae9a8..0e955d59ff8 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: "#{@group.name}"
- %body{class: "#{app_theme} application"}
+ %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/head_panel", title: "group: #{@group.name}"
= render "layouts/flash"
%nav.main-nav
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index 535f94c4ef6..30a0532bc2b 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: "Profile"
- %body{class: "#{app_theme} profile"}
+ %body{class: "#{app_theme} profile", :'data-page' => body_data_page}
= render "layouts/head_panel", title: "Profile"
= render "layouts/flash"
%nav.main-nav
diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml
index 7b0d4789f8e..1fc36410668 100644
--- a/app/views/layouts/project_resource.html.haml
+++ b/app/views/layouts/project_resource.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: @project.name_with_namespace
- %body{class: "#{app_theme} project"}
+ %body{class: "#{app_theme} project", :'data-page' => body_data_page, :'data-project-id' => @project.id }
= render "layouts/head_panel", title: project_title(@project)
= render "layouts/flash"
- if can?(current_user, :download_code, @project)
diff --git a/app/views/layouts/user_team.html.haml b/app/views/layouts/user_team.html.haml
index f2ead9d242a..e64e68d2446 100644
--- a/app/views/layouts/user_team.html.haml
+++ b/app/views/layouts/user_team.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{ lang: "en"}
= render "layouts/head", title: "#{@team.name}"
- %body{class: "#{app_theme} application"}
+ %body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/head_panel", title: "team: #{@team.name}"
= render "layouts/flash"
%nav.main-nav
diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml
index 6d64988c15a..1c3aca176ab 100644
--- a/app/views/merge_requests/_form.html.haml
+++ b/app/views/merge_requests/_form.html.haml
@@ -40,7 +40,7 @@
= f.label :assignee_id do
%i.icon-user
Assign to
- .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
+ .input= f.select(:assignee_id, @project.users.alphabetically.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'})
.left
= f.label :milestone_id do
%i.icon-time
diff --git a/app/views/merge_requests/_show.html.haml b/app/views/merge_requests/_show.html.haml
index 08b80172645..d6e00ca9b8b 100644
--- a/app/views/merge_requests/_show.html.haml
+++ b/app/views/merge_requests/_show.html.haml
@@ -26,14 +26,12 @@
:javascript
var merge_request;
- $(function(){
- merge_request = new MergeRequest({
- url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
- check_enable: #{@merge_request.unchecked? ? "true" : "false"},
- url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
- ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
- current_status: "#{@merge_request.merge_status_name}",
- action: "#{controller.action_name}"
- });
- });
+ merge_request = new MergeRequest({
+ url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
+ check_enable: #{@merge_request.unchecked? ? "true" : "false"},
+ url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
+ ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
+ current_status: "#{@merge_request.merge_status_name}",
+ action: "#{controller.action_name}"
+ });
diff --git a/app/views/merge_requests/show/_how_to_merge.html.haml b/app/views/merge_requests/show/_how_to_merge.html.haml
index 69881d4352f..7f1e33418de 100644
--- a/app/views/merge_requests/show/_how_to_merge.html.haml
+++ b/app/views/merge_requests/show/_how_to_merge.html.haml
@@ -3,22 +3,17 @@
%a.close{href: "#"} ×
%h3 How To Merge
.modal-body
+ %p
+ %strong Step 1.
+ Checkout target branch and get recent objects from GitLab
%pre.dark
- = preserve do
+ :preserve
git checkout #{@merge_request.target_branch}
git fetch origin
+ %p
+ %strong Step 2.
+ Merge source branch into target branch and push changes to GitLab
+ %pre.dark
+ :preserve
git merge origin/#{@merge_request.source_branch}
git push origin #{@merge_request.target_branch}
-
-
-:javascript
- $(function(){
- var modal = $('#modal_merge_info').modal({modal: true, show:false});
- $('.how_to_merge_link').bind("click", function(){
- modal.show();
- });
- $('.modal-header .close').bind("click", function(){
- modal.hide();
- })
- })
-
diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml
index 3b54f613f58..594f4061c23 100644
--- a/app/views/merge_requests/show/_mr_box.html.haml
+++ b/app/views/merge_requests/show/_mr_box.html.haml
@@ -1,13 +1,13 @@
.ui-box.ui-box-show
.ui-box-head
%h4.box-title
+ = gfm escape_once(@merge_request.title)
- if @merge_request.merged?
- .error.status_info
+ .success.status_info
%i.icon-ok
Merged
- elsif @merge_request.closed?
.error.status_info Closed
- = gfm escape_once(@merge_request.title)
.ui-box-body
%div
@@ -22,13 +22,15 @@
- if @merge_request.closed?
- .ui-box-bottom
+ .ui-box-bottom.alert-error
%span
+ %i.icon-remove
Closed by #{link_to_member(@project, @merge_request.closed_event.author)}
%small #{time_ago_in_words(@merge_request.closed_event.created_at)} ago.
- if @merge_request.merged?
- .ui-box-bottom
+ .ui-box-bottom.alert-success
%span
+ %i.icon-ok
Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
- %small #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
+ #{time_ago_in_words(@merge_request.merge_event.created_at)} ago.
diff --git a/app/views/merge_requests/show/_mr_ci.html.haml b/app/views/merge_requests/show/_mr_ci.html.haml
index a8faa6ba617..9b15c4526e9 100644
--- a/app/views/merge_requests/show/_mr_ci.html.haml
+++ b/app/views/merge_requests/show/_mr_ci.html.haml
@@ -1,4 +1,4 @@
-- if @merge_request.opened? && @commits.any?
+- if @commits.any?
.ci_widget.ci-success{style: "display:none"}
.alert.alert-success
%i.icon-ok
diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml
index 8a3727c6f6a..894fa6c1133 100644
--- a/app/views/milestones/_milestone.html.haml
+++ b/app/views/milestones/_milestone.html.haml
@@ -4,6 +4,8 @@
= link_to edit_project_milestone_path(milestone.project, milestone), class: "btn btn-small edit-milestone-link grouped" do
%i.icon-edit
Edit
+ - if milestone.can_be_closed?
+ = link_to 'Close', project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-small btn-remove"
%h4
= link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone)
- if milestone.expired? and not milestone.closed?
@@ -13,11 +15,8 @@
- if milestone.is_empty?
%span.muted Empty
- else
- .row
- .span4
- .progress.progress-info
- .bar{style: "width: #{milestone.percent_complete}%;"}
- .span6
+ %div
+ %div
= link_to project_issues_path(milestone.project, milestone_id: milestone.id) do
= pluralize milestone.issues.count, 'Issue'
&nbsp;
@@ -25,3 +24,5 @@
= pluralize milestone.merge_requests.count, 'Merge Request'
&nbsp;
%span.light #{milestone.percent_complete}% complete
+ .progress.progress-info
+ .bar{style: "width: #{milestone.percent_complete}%;"}
diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml
index b78f17053fd..89892cd23f1 100644
--- a/app/views/milestones/index.html.haml
+++ b/app/views/milestones/index.html.haml
@@ -3,11 +3,14 @@
%h3.page_title
Milestones
- if can? current_user, :admin_milestone, @project
- = link_to "New Milestone", new_project_milestone_path(@project), class: "pull-right btn btn-small", title: "New Milestone"
+ = link_to new_project_milestone_path(@project), class: "pull-right btn btn-primary", title: "New Milestone" do
+ %i.icon-plus
+ New Milestone
%br
- %div.ui-box
- .title
- %ul.nav.nav-pills
+
+ .row
+ .span3
+ %ul.nav.nav-pills.nav-stacked
%li{class: ("active" if (params[:f] == "active" || !params[:f]))}
= link_to project_milestones_path(@project, f: "active") do
Active
@@ -17,12 +20,13 @@
%li{class: ("active" if params[:f] == "all")}
= link_to project_milestones_path(@project, f: "all") do
All
+ .span9
+ %div.ui-box
+ %ul.well-list
+ = render @milestones
- %ul.well-list
- = render @milestones
-
- - if @milestones.present?
- %li.bottom= paginate @milestones, theme: "gitlab"
- - else
- %li
- %h3.nothing_here_message Nothing to show here
+ - if @milestones.present?
+ %li.bottom= paginate @milestones, theme: "gitlab"
+ - else
+ %li
+ %h3.nothing_here_message Nothing to show here
diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml
index 30539af48d8..034c37852f1 100644
--- a/app/views/milestones/show.html.haml
+++ b/app/views/milestones/show.html.haml
@@ -1,3 +1,4 @@
+= render "issues/head"
.row
.span6
%h3.page_title
@@ -87,7 +88,6 @@
%h6 Participants:
%div
- @users.each do |user|
- = link_to user do
- = link_to_member(@project, user)
+ = link_to_member(@project, user)
.clearfix
diff --git a/app/views/milestones/update.js.haml b/app/views/milestones/update.js.haml
new file mode 100644
index 00000000000..3ff84915e97
--- /dev/null
+++ b/app/views/milestones/update.js.haml
@@ -0,0 +1,2 @@
+:plain
+ $('##{dom_id(@milestone)}').fadeOut();
diff --git a/app/views/notes/_notes_with_form.html.haml b/app/views/notes/_notes_with_form.html.haml
index 2566edd81ad..38d1a3c93c0 100644
--- a/app/views/notes/_notes_with_form.html.haml
+++ b/app/views/notes/_notes_with_form.html.haml
@@ -6,6 +6,4 @@
= render "notes/form"
:javascript
- $(function(){
- NoteList.init("#{@target_id}", "#{@target_type}", "#{project_notes_path(@project)}");
- });
+ NoteList.init("#{@target_id}", "#{@target_type}", "#{project_notes_path(@project)}");
diff --git a/app/views/notifications/show.html.haml b/app/views/notifications/show.html.haml
index 38e492f2d1b..b7f39306fd8 100644
--- a/app/views/notifications/show.html.haml
+++ b/app/views/notifications/show.html.haml
@@ -15,7 +15,7 @@
.row
.span4
- %h5 Global
+ %h5 Global setting
.span7
= form_tag profile_notifications_path, method: :put, remote: true, class: 'update-notifications' do
= hidden_field_tag :notification_type, 'global'
@@ -36,7 +36,7 @@
= link_to '#', class: 'js-toggle-visibility-link' do
%h6.btn.btn-tiny
%i.icon-chevron-down
- %span Per project notifications settings
+ %span Per project notifications setting
%ul.well-list.js-toggle-visibility-container.hide
- @users_projects.each do |users_project|
@@ -53,7 +53,7 @@
= label_tag do
= radio_button_tag :notification_level, Notification::N_GLOBAL, notification.global?, id: dom_id(users_project, 'notification_level'), class: 'trigger-submit'
- %span Use global settings
+ %span Use global setting
= label_tag do
= radio_button_tag :notification_level, Notification::N_DISABLED, notification.disabled?, id: dom_id(users_project, 'notification_level'), class: 'trigger-submit'
diff --git a/app/views/profiles/design.html.haml b/app/views/profiles/design.html.haml
index 77068dabb32..878297fe49d 100644
--- a/app/views/profiles/design.html.haml
+++ b/app/views/profiles/design.html.haml
@@ -55,3 +55,8 @@
= image_tag "solarized_dark.png"
= f.radio_button :color_scheme_id, 3
Solarized Dark
+ = label_tag do
+ .prev
+ = image_tag "monokai.png"
+ = f.radio_button :color_scheme_id, 4
+ Monokai
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index f63729ffdf6..d4793da8987 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -51,7 +51,7 @@
%legend Tips:
%ul
%li
- %p You can change your password on Account page
+ %p You can change your password on the Account page
- if Gitlab.config.gravatar.enabled
%li
%p You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"}
diff --git a/app/views/projects/_clone_panel.html.haml b/app/views/projects/_clone_panel.html.haml
index 7b90f80985c..02b09ab73d9 100644
--- a/app/views/projects/_clone_panel.html.haml
+++ b/app/views/projects/_clone_panel.html.haml
@@ -1,20 +1,42 @@
.project_clone_panel
.row
- .span7
+ .span8
.form-horizontal= render "shared/clone_panel"
- .span4.pull-right
+ .span3.pull-right
.pull-right
- unless @project.empty_repo?
- if can? current_user, :fork_project, @project
= link_to fork_project_path(@project), title: "Fork", class: "btn small grouped", method: "POST" do
Fork
- if can? current_user, :download_code, @project
- = link_to archive_project_repository_path(@project), class: "btn-small btn grouped" do
+ = link_to archive_project_repository_path(@project), class: "btn grouped" do
%i.icon-download-alt
Download
- - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project)
- = link_to new_project_merge_request_path(@project), title: "New Merge Request", class: "btn-small btn grouped" do
- Merge Request
- - if @project.issues_enabled && can?(current_user, :write_issue, @project)
- = link_to url_for_new_issue, title: "New Issue", class: "btn-small btn grouped" do
- Issue
+
+ = link_to tags_project_repository_path(@project), class: "btn grouped only-wide", title: 'Git Tags' do
+ %i.icon-tags
+
+ .dropdown.pull-right
+ %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
+ %i.icon-plus
+ Add new
+ %b.caret
+ %ul.dropdown-menu
+ - if @project.issues_enabled && can?(current_user, :write_issue, @project)
+ %li
+ = link_to url_for_new_issue, title: "New Issue" do
+ Issue
+ - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project)
+ %li
+ = link_to new_project_merge_request_path(@project), title: "New Merge Request" do
+ Merge Request
+ - if @project.snippets_enabled && can?(current_user, :write_snippet, @project)
+ %li
+ = link_to new_project_snippet_path(@project), title: "New Snippet" do
+ Snippet
+ - if can?(current_user, :admin_team_member, @project)
+ %li.divider
+ %li
+ = link_to new_project_team_member_path(@project), title: "New Team member" do
+ Team member
+
diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml
index 4d51e10dc3e..4d635e3dc68 100644
--- a/app/views/projects/_form.html.haml
+++ b/app/views/projects/_form.html.haml
@@ -59,6 +59,15 @@
%fieldset.features
%legend
+ Labels:
+ .control-group
+ = f.label :label_list, "Labels", class: 'control-label'
+ .controls
+ = f.text_field :label_list, maxlength: 2000, class: "span5"
+ %p.hint Separate with comma.
+
+ %fieldset.features
+ %legend
Features:
.control-group
= f.label :issues_enabled, "Issues", class: 'control-label'
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index c050f9454a5..e215ad6fd73 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -8,6 +8,3 @@
%center
= image_tag "ajax_loader.gif"
%h3 Saving project. Please wait a moment, this page will automatically refresh when ready.
-
-:javascript
- $(function(){ new Projects(); });
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index eb4ef5979cf..8ff873aac65 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -7,6 +7,3 @@
%center
= image_tag "ajax_loader.gif"
%h3 Creating project &amp; repository. Please wait a moment, this page will automatically refresh when ready.
-
-:javascript
- $(function(){ new Projects(); });
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 824d4daf698..6edfd2ed401 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -1,32 +1,19 @@
= render 'clone_panel'
-= render "events/event_last_push", event: @last_push
.row
.span9
+ = render "events/event_last_push", event: @last_push
.content_list= render @events
.loading.hide
.span3
- .ui-box.white
- .padded
- %h3.page_title
- = @project.name
- - if @project.description.present?
- %p.light= @project.description
+ .light-well
+ %h3.page_title
+ = @project.name
+ - if @project.description.present?
+ %p.light= @project.description
- %hr
- %p
- Access level:
- - if @project.public
- %span.cblue
- %i.icon-share
- Public
- - else
- %span.cgreen
- %i.icon-lock
- Private
-
- %p Repo Size: #{@project.repository.size} MB
- %p Created at: #{@project.created_at.stamp('Aug 22, 2013')}
- %p Owner: #{link_to @project.owner_name, @project.owner}
-:javascript
- $(function(){ Pager.init(20); });
+ %hr
+ %p
+ %p Repo Size: #{@project.repository.size} MB
+ %p Created at: #{@project.created_at.stamp('Aug 22, 2013')}
+ %p Owner: #{link_to @project.owner_name, @project.owner}
diff --git a/app/views/projects/tree.js.haml b/app/views/projects/tree.js.haml
deleted file mode 100644
index ba5d53c16a2..00000000000
--- a/app/views/projects/tree.js.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-:plain
- $("#tree-holder table").hide("slide", { direction: "left" }, 150, function(){
- $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {repo: @repo, commit: @commit, tree: @tree}))}");
- $("#tree-holder table").show("slide", { direction: "right" }, 150);
- });
diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml
index d448c669271..6d1fb4686ea 100644
--- a/app/views/repositories/stats.html.haml
+++ b/app/views/repositories/stats.html.haml
@@ -27,9 +27,7 @@
:javascript
- $(function(){
- var labels = [#{@graph.labels.to_json}];
- var commits = [#{@graph.commits.join(', ')}];
- var title = "Commit activity for last #{@graph.weeks} weeks";
- Chart.init(labels, commits, title);
- })
+ var labels = [#{@graph.labels.to_json}];
+ var commits = [#{@graph.commits.join(', ')}];
+ var title = "Commit activity for last #{@graph.weeks} weeks";
+ Chart.init(labels, commits, title);
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index bd9ca729352..9e5b8dade56 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -1,4 +1,13 @@
-.input-prepend.project_clone_holder
+.input-prepend.input-append.project_clone_holder
%button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH
%button{class: "btn", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
- = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select input-xxlarge", readonly: true
+ = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span7", readonly: true
+ %span.add-on
+ - if @project.public
+ .cblue
+ %i.icon-share
+ public
+ - else
+ .cgreen
+ %i.icon-lock
+ private
diff --git a/app/views/shared/_promo.html.haml b/app/views/shared/_promo.html.haml
new file mode 100644
index 00000000000..c97f8ba0f0e
--- /dev/null
+++ b/app/views/shared/_promo.html.haml
@@ -0,0 +1,4 @@
+.gitlab-promo
+ = link_to "Homepage", "http://gitlab.org"
+ = link_to "Blog", "http://blog.gitlab.org"
+ = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
diff --git a/app/views/team_members/_team.html.haml b/app/views/team_members/_team.html.haml
index 2ec8c1a8451..4b49b308edc 100644
--- a/app/views/team_members/_team.html.haml
+++ b/app/views/team_members/_team.html.haml
@@ -1,8 +1,9 @@
- team.each do |access, members|
- .ui-box
+ - role = Project.access_options.key(access).pluralize
+ .ui-box{class: role.downcase}
%h5.title
- = Project.access_options.key(access).pluralize
- %small= members.size
+ = role
+ %span.light (#{members.size})
%ul.well-list
- members.sort_by(&:user_name).each do |team_member|
= render 'team_members/team_member', member: team_member
diff --git a/app/views/team_members/_team_member.html.haml b/app/views/team_members/_team_member.html.haml
index 2b0709beb92..5fd8d2465d1 100644
--- a/app/views/team_members/_team_member.html.haml
+++ b/app/views/team_members/_team_member.html.haml
@@ -16,11 +16,11 @@
= f.select :project_access, options_for_select(UsersProject.access_roles, member.project_access), {}, class: "medium project-access-select span2 trigger-submit"
.pull-right
- if current_user == user
- %span.label This is you!
+ %span.label.label-success This is you!
- if @project.namespace_owner == user
- %span.label Owner
+ %span.label.label-info Owner
- elsif user.blocked?
- %span.label Blocked
+ %span.label.label-error Blocked
- elsif allow_admin
= link_to project_team_member_path(@project, user), confirm: remove_from_project_team_message(@project, user), method: :delete, class: "btn-tiny btn btn-remove", title: 'Remove user from team' do
%i.icon-minus.icon-white
diff --git a/app/views/team_members/create.js.haml b/app/views/team_members/create.js.haml
deleted file mode 100644
index b7dff35a269..00000000000
--- a/app/views/team_members/create.js.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-- if @user_project_relation.valid?
- :plain
- $("#new_team_member").hide("slide", { direction: "right" }, 150, function(){
- $("#team-table").show("slide", { direction: "left" }, 150, function() {
- $("#new_team_member").remove();
- $("#team-table").replaceWith("#{escape_javascript(render('projects/team'))}");
- $(".add_new").show();
- });
- });
-- else
- :plain
- $("#new_team_member").replaceWith("#{escape_javascript(render('form'))}");
- $('select#team_member_user_id').chosen();
diff --git a/app/views/teams/members/_show.html.haml b/app/views/teams/members/_show.html.haml
index 1a323043d09..dc32acb4693 100644
--- a/app/views/teams/members/_show.html.haml
+++ b/app/views/teams/members/_show.html.haml
@@ -2,7 +2,7 @@
- allow_admin = can? current_user, :manage_user_team, @team
%li{id: dom_id(member), class: "team_member_row user_#{user.id}"}
.row
- .span5
+ .span4
= link_to user_path(user.username), title: user.name, class: "dark" do
= image_tag gravatar_icon(user.email, 40), class: "avatar s32"
= link_to user_path(user.username), title: user.name, class: "dark" do
@@ -10,21 +10,22 @@
%br
%small.cgray= user.username
- .span4
+ .span7.pull-right
- if allow_admin
- = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
- = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium trigger-submit"
- %br
- = label_tag do
- = f.check_box :group_admin, class: 'trigger-submit'
- %span Admin access
- .pull-right
- - if current_user == user
- %span.btn.disabled This is you!
- - if @team.owner == user
- %span.btn.disabled Owner
- - elsif user.blocked?
- %span.btn.disabled.blocked Blocked
- - elsif allow_admin
- = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
- %i.icon-minus.icon-white
+ .pull-left
+ = form_for(member, as: :team_member, url: team_member_path(@team, user)) do |f|
+ = label_tag do
+ = f.check_box :group_admin, class: 'trigger-submit'
+ %span Admin access
+ &nbsp;
+ = f.select :permission, options_for_select(UsersProject.access_roles, @team.default_projects_access(user)), {}, class: "medium trigger-submit"
+ .pull-right
+ - if current_user == user
+ %span.btn.disabled This is you!
+ - if @team.owner == user
+ %span.btn.disabled Owner
+ - elsif user.blocked?
+ %span.btn.disabled.blocked Blocked
+ - elsif allow_admin
+ = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
+ %i.icon-minus.icon-white
diff --git a/app/views/teams/members/new.html.haml b/app/views/teams/members/new.html.haml
index 9b9b3cef59b..99530ebb7f0 100644
--- a/app/views/teams/members/new.html.haml
+++ b/app/views/teams/members/new.html.haml
@@ -1,29 +1,25 @@
%h3.page_title
Team: #{@team.name}
-%fieldset
- %legend Members (#{@team.members.count})
- = form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
- %table#members_list
- %thead
- %tr
- %th User name
- %th Default project access
- %th Team access
- %th
- - @team.members.each do |member|
- %tr.member
- %td
- = member.name
- %small= "(#{member.username})"
- %td= @team.human_default_projects_access(member)
- %td= @team.admin?(member) ? "Admin" : "Member"
- %td
- %tr
- %td
- = users_select_tag(:user_ids, multiple: true)
- %td= select_tag :default_project_access, options_for_select(Project.access_options), {class: "project-access-select chosen span3" }
- %td
- %span= check_box_tag :group_admin
- %span Admin?
- %td= submit_tag 'Add User', class: "btn btn-create", id: :add_members_to_team
+%hr
+
+= form_tag team_members_path(@team), id: "team_members", class: "bulk_import", method: :post do
+ %h6 1. Choose people you want in the team
+ .clearfix
+ = label_tag :user_ids, "People"
+ .input
+ = users_select_tag(:user_ids, multiple: true)
+
+ %h6 2. Set access level for them
+ .clearfix
+ = label_tag :project_access, "Project Access"
+ .input= select_tag :default_project_access, options_for_select(Project.access_options), class: "project-access-select chosen"
+
+ .clearfix
+ = label_tag :group_admin do
+ %span Team Admin?
+ .input= check_box_tag :group_admin
+
+ .actions
+ = submit_tag 'Add users', class: "btn btn-create", id: :add_members_to_team
+ = link_to "Cancel", team_members_path(@team), class: "btn btn-cancel"
diff --git a/app/views/teams/show.html.haml b/app/views/teams/show.html.haml
index 88cffa011ed..2ad7f743010 100644
--- a/app/views/teams/show.html.haml
+++ b/app/views/teams/show.html.haml
@@ -22,10 +22,4 @@
News Feed
%hr
- .gitlab-promo
- = link_to "Homepage", "http://gitlabhq.com"
- = link_to "Blog", "http://blog.gitlabhq.com"
- = link_to "@gitlabhq", "https://twitter.com/gitlabhq"
-
-:javascript
- $(function(){ Pager.init(20, true); });
+ = render 'shared/promo'
diff --git a/app/views/tree/_tree.html.haml b/app/views/tree/_tree.html.haml
index f77b8983726..cc45faa1459 100644
--- a/app/views/tree/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -17,7 +17,15 @@
%tr
%th Name
%th Last Update
- %th Last Commit
+ %th
+ Last Commit
+ &nbsp;
+ %i.icon-angle-right
+ &nbsp;
+ %small.light
+ = link_to @commit.short_id, project_commit_path(@project, @commit)
+ &ndash;
+ = truncate(@commit.title, length: 50)
%th= link_to "history", project_commits_path(@project, @id), class: "btn btn-tiny pull-right"
- if tree.up_dir?
@@ -38,6 +46,6 @@
:javascript
// Load last commit log for each file in tree
- $(window).load(function(){
+ $('#tree-slider').waitForImages(function() {
ajaxGet('#{@logs_path}');
});
diff --git a/app/views/tree/show.js.haml b/app/views/tree/show.js.haml
deleted file mode 100644
index a01d49179b9..00000000000
--- a/app/views/tree/show.js.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-:plain
- // Load Files list
- $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {tree: @tree}))}");
- $("#tree-content-holder").show("slide", { direction: "right" }, 400);
- $('.project-refs-form #path').val("#{@path}");
-
- // Load last commit log for each file in tree
- $('#tree-slider').waitForImages(function() {
- ajaxGet('#{@logs_path}');
- });
diff --git a/app/views/walls/show.html.haml b/app/views/walls/show.html.haml
index 139e66f5dd0..88aecee0815 100644
--- a/app/views/walls/show.html.haml
+++ b/app/views/walls/show.html.haml
@@ -21,8 +21,3 @@
.hint.pull-right CTRL + Enter to send message
.clearfix
-
-:javascript
- $(function(){
- Wall.init(#{@project.id});
- });
diff --git a/app/views/wikis/_nav.html.haml b/app/views/wikis/_nav.html.haml
index 0dffdd8fc14..09a1986e105 100644
--- a/app/views/wikis/_nav.html.haml
+++ b/app/views/wikis/_nav.html.haml
@@ -11,8 +11,8 @@
Git Access
- if can?(current_user, :write_wiki, @project)
- %li.pull-right
- = link_to '#', class: "add-new-wiki" do
+ .pull-right
+ = link_to '#', class: "add-new-wiki btn btn-small btn-primary" do
%i.icon-plus
New Page
diff --git a/app/views/wikis/_new.html.haml b/app/views/wikis/_new.html.haml
index 50b40bff41c..ca8e7c1b4b4 100644
--- a/app/views/wikis/_new.html.haml
+++ b/app/views/wikis/_new.html.haml
@@ -1,25 +1,12 @@
%div#modal-new-wiki.modal.hide
.modal-header
%a.close{href: "#"} ×
- %h3 New Wiki Page
+ %h3.page_title New Wiki Page
.modal-body
= label_tag :new_wiki_path do
%span Page slug
- = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'input-xlarge'
+ = text_field_tag :new_wiki_path, nil, placeholder: 'how-to-setup', class: 'input-xlarge', required: true, :'data-wikis-path' => project_wikis_path(@project)
+ %p.hint
+ Please dont use spaces and slashes
.modal-footer
= link_to 'Build', '#', class: 'build-new-wiki btn btn-create'
-
-:javascript
- $(function(){
- var modal = $('#modal-new-wiki').modal({modal: true, show:false});
- $('.add-new-wiki').bind("click", function(){
- modal.show();
- });
- $('.build-new-wiki').bind("click", function(){
- location.href = "#{project_wikis_path(@project)}/" + $('#new_wiki_path').val();
- });
- $('.modal-header .close').bind("click", function(){
- modal.hide();
- })
- })
-
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 132f1a6d7e9..6416aa608ec 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -1,5 +1,6 @@
class PostReceive
include Sidekiq::Worker
+ include Gitlab::Identifier
sidekiq_options queue: :post_receive
@@ -8,7 +9,7 @@ class PostReceive
if repo_path.start_with?(Gitlab.config.gitlab_shell.repos_path.to_s)
repo_path.gsub!(Gitlab.config.gitlab_shell.repos_path.to_s, "")
else
- Gitlab::GitLogger.error("POST-RECEIVE: Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"")
+ log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"")
end
repo_path.gsub!(/.git$/, "")
@@ -17,31 +18,21 @@ class PostReceive
project = Project.find_with_namespace(repo_path)
if project.nil?
- Gitlab::GitLogger.error("POST-RECEIVE: Triggered hook for non-existing project with full path \"#{repo_path} \"")
+ log("Triggered hook for non-existing project with full path \"#{repo_path} \"")
return false
end
- user = if identifier.blank?
- # Local push from gitlab
- email = project.repository.commit(newrev).author_email rescue nil
- User.find_by_email(email) if email
-
- elsif identifier =~ /\Auser-\d+\Z/
- # git push over http
- user_id = identifier.gsub("user-", "")
- User.find_by_id(user_id)
-
- elsif identifier =~ /\Akey-\d+\Z/
- # git push over ssh
- key_id = identifier.gsub("key-", "")
- Key.find_by_id(key_id).try(:user)
- end
+ user = identify(identifier, project, newrev)
unless user
- Gitlab::GitLogger.error("POST-RECEIVE: Triggered hook for non-existing user \"#{identifier} \"")
+ log("Triggered hook for non-existing user \"#{identifier} \"")
return false
end
GitPushService.new.execute(project, user, oldrev, newrev, ref)
end
+
+ def log(message)
+ Gitlab::GitLogger.error("POST-RECEIVE: #{message}")
+ end
end
diff --git a/config/aws.yml.example b/config/aws.yml.example
new file mode 100644
index 00000000000..29d029b078d
--- /dev/null
+++ b/config/aws.yml.example
@@ -0,0 +1,19 @@
+# See https://github.com/jnicklas/carrierwave#using-amazon-s3
+# for more options
+production:
+ access_key_id: AKIA1111111111111UA
+ secret_access_key: secret
+ bucket: mygitlab.production.us
+ region: us-east-1
+
+development:
+ access_key_id: AKIA1111111111111UA
+ secret_access_key: secret
+ bucket: mygitlab.development.us
+ region: us-east-1
+
+test:
+ access_key_id: AKIA1111111111111UA
+ secret_access_key: secret
+ bucket: mygitlab.test.us
+ region: us-east-1
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 90d04b390c3..0ba8b5d211f 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -37,6 +37,13 @@ production: &base
# signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled.
# username_changing_enabled: false # default: true - User can change her username/namespace
+ ## Default project features settings
+ default_projects_features:
+ issues: true
+ merge_requests: true
+ wiki: true
+ wall: false
+ snippets: false
## External issues trackers
issues_tracker:
@@ -159,7 +166,7 @@ test:
redmine:
project_url: "http://redmine/projects/:issues_tracker_id"
issues_url: "http://redmine/:project_id/:issues_tracker_id/:id"
- new_issue_url: "http://redmine/projects/:issues_tracker_id/insues/new"
+ new_issue_url: "http://redmine/projects/:issues_tracker_id/issues/new"
staging:
<<: *base
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index ac35eef4218..be5393b0483 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -60,6 +60,12 @@ Settings.gitlab['url'] ||= Settings.send(:build_gitlab_url)
Settings.gitlab['user'] ||= 'git'
Settings.gitlab['signup_enabled'] ||= false
Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
+Settings.gitlab['default_projects_features'] ||= {}
+Settings.gitlab.default_projects_features['issues'] = true if Settings.gitlab.default_projects_features['issues'].nil?
+Settings.gitlab.default_projects_features['merge_requests'] = true if Settings.gitlab.default_projects_features['merge_requests'].nil?
+Settings.gitlab.default_projects_features['wiki'] = true if Settings.gitlab.default_projects_features['wiki'].nil?
+Settings.gitlab.default_projects_features['wall'] = false if Settings.gitlab.default_projects_features['wall'].nil?
+Settings.gitlab.default_projects_features['snippets'] = false if Settings.gitlab.default_projects_features['snippets'].nil?
#
# Gravatar
diff --git a/config/initializers/3_grit_ext.rb b/config/initializers/3_grit_ext.rb
index 097c301a06a..2728f51c3ea 100644
--- a/config/initializers/3_grit_ext.rb
+++ b/config/initializers/3_grit_ext.rb
@@ -3,7 +3,3 @@ require 'pygments'
Grit::Git.git_timeout = Gitlab.config.git.timeout
Grit::Git.git_max_size = Gitlab.config.git.max_size
-
-Grit::Blob.class_eval do
- include Linguist::BlobHelper
-end
diff --git a/config/initializers/5_backend.rb b/config/initializers/5_backend.rb
index 7c2e7f39000..e60d9559c94 100644
--- a/config/initializers/5_backend.rb
+++ b/config/initializers/5_backend.rb
@@ -6,3 +6,6 @@ require Rails.root.join("lib", "gitlab", "backend", "shell")
# GitLab shell adapter
require Rails.root.join("lib", "gitlab", "backend", "shell_adapter")
+
+# Gitlab Git repos path
+Gitlab::Git::Repository.repos_path = Gitlab.config.gitlab_shell.repos_path
diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb
index 9bb62f6d55a..6659c1a1f7c 100644
--- a/config/initializers/carrierwave.rb
+++ b/config/initializers/carrierwave.rb
@@ -1 +1,17 @@
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
+
+aws_file = Rails.root.join('config', 'aws.yml')
+
+if File.exists?(aws_file)
+ AWS_CONFIG = YAML.load(File.read(aws_file))[Rails.env]
+
+ config.fog_credentials = {
+ provider: 'AWS', # required
+ aws_access_key_id: AWS_CONFIG['access_key_id'], # required
+ aws_secret_access_key: AWS_CONFIG['secret_access_key'], # required
+ region: AWS_CONFIG['region'], # optional, defaults to 'us-east-1'
+ }
+ config.fog_directory = AWS_CONFIG['bucket'] # required
+ config.fog_public = false # optional, defaults to true
+ config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
+end
diff --git a/config/unicorn.rb.example b/config/unicorn.rb.example
deleted file mode 100644
index 75945182806..00000000000
--- a/config/unicorn.rb.example
+++ /dev/null
@@ -1,68 +0,0 @@
-# uncomment and customize to run in non-root path
-# note that config/gitlab.yml web path should also be changed
-# ENV['RAILS_RELATIVE_URL_ROOT'] = "/gitlab"
-
-app_dir = File.expand_path '../../', __FILE__
-worker_processes 2
-working_directory app_dir
-
-# Load app into the master before forking workers for super-fast
-# worker spawn times
-preload_app true
-
-# nuke workers after 30 seconds (60 is the default)
-timeout 30
-
-# listen on a Unix domain socket and/or a TCP port,
-
-#listen 8080 # listen to port 8080 on all TCP interfaces
-#listen "127.0.0.1:8080" # listen to port 8080 on the loopback interface
-listen "#{app_dir}/tmp/sockets/gitlab.socket"
-
-pid "#{app_dir}/tmp/pids/unicorn.pid"
-stderr_path "#{app_dir}/log/unicorn.stderr.log"
-stdout_path "#{app_dir}/log/unicorn.stdout.log"
-
-# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
-if GC.respond_to?(:copy_on_write_friendly=)
- GC.copy_on_write_friendly = true
-end
-
-
-before_fork do |server, worker|
- # the following is highly recommended for Rails + "preload_app true"
- # as there's no need for the master process to hold a connection
- defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
-
- ##
- # When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
- # immediately start loading up a new version of itself (loaded with a new
- # version of our app). When this new Unicorn is completely loaded
- # it will begin spawning workers. The first worker spawned will check to
- # see if an .oldbin pidfile exists. If so, this means we've just booted up
- # a new Unicorn and need to tell the old one that it can now die. To do so
- # we send it a QUIT.
- #
- # Using this method we get 0 downtime deploys.
-
- old_pid = "#{server.config[:pid]}.oldbin"
-
- if File.exists?(old_pid) && server.pid != old_pid
- begin
- sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
- Process.kill(sig, File.read(old_pid).to_i)
- rescue Errno::ENOENT, Errno::ESRCH
- # someone else did our job for us
- end
- end
-end
-
-after_fork do |server, worker|
- # Unicorn master loads the app then forks off workers - because of the way
- # Unix forking works, we need to make sure we aren't using any of the parent's
- # sockets, e.g. db connection
-
- defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
- # Redis and Memcached would go here but their connections are established
- # on demand, so the master never opens a socket
-end
diff --git a/db/fixtures/development/02_source_code.rb b/db/fixtures/development/02_source_code.rb
index a0a46c9e927..5ce5bcf4aba 100644
--- a/db/fixtures/development/02_source_code.rb
+++ b/db/fixtures/development/02_source_code.rb
@@ -1,3 +1,4 @@
+gitlab_shell_path = File.expand_path("~#{Gitlab.config.gitlab_shell.ssh_user}")
root = Gitlab.config.gitlab_shell.repos_path
projects = [
@@ -17,8 +18,7 @@ projects.each do |project|
print '-'
next
end
-
- if system("/home/git/gitlab-shell/bin/gitlab-projects import-project #{project[:path]} #{project[:git]}")
+ if system("#{gitlab_shell_path}/gitlab-shell/bin/gitlab-projects import-project #{project[:path]} #{project[:git]}")
print '.'
else
print 'F'
diff --git a/doc/api/projects.md b/doc/api/projects.md
index d6a9a8854ca..d3d15ab4e02 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -313,7 +313,7 @@ Removes a hook from project. This is an idempotent method and can be called mult
Either the hook is available or not.
```
-DELETE /projects/:id/hooks/
+DELETE /projects/:id/hooks/:hook_id
```
Parameters:
diff --git a/doc/api/users.md b/doc/api/users.md
index c05bcb3e539..ee5e98a016c 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -1,6 +1,7 @@
## List users
Get a list of users.
+This function takes pagination parameters `page` and `per_page` to restrict the list of users.
```
GET /users
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 41202b09b74..9734034bf84 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -42,7 +42,7 @@ edited by hand. But, you can use any editor you like instead.
Install the required packages:
- sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl git-core openssh-server redis-server postfix checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev
+ sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libreadline-dev libncurses5-dev libffi-dev curl git-core openssh-server redis-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev
Make sure you have the right version of Python installed.
@@ -61,6 +61,11 @@ Make sure you have the right version of Python installed.
# If you get a "command not found" error create a link to the python binary
sudo ln -s /usr/bin/python /usr/bin/python2
+**Note:** In order to receive mail notifications, make sure to install a
+mail server. By default, Debian is shipped with exim4 whereas Ubuntu
+does not ship with one. The recommended mail server is postfix and you can install it with:
+
+ sudo apt-get install postfix
# 2. Ruby
@@ -99,6 +104,10 @@ GitLab Shell is a ssh access and repository management software developed specia
git clone https://github.com/gitlabhq/gitlab-shell.git
cd gitlab-shell
+
+ # switch to right version
+ git checkout v1.3.0
+
cp config.yml.example config.yml
# Edit config and replace gitlab_url
@@ -128,10 +137,10 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install
cd /home/git/gitlab
# Checkout to stable release
- sudo -u git -H git checkout 5-0-stable
+ sudo -u git -H git checkout 5-1-stable
**Note:**
-You can change `5-0-stable` to `master` if you want the *bleeding edge* version, but
+You can change `5-1-stable` to `master` if you want the *bleeding edge* version, but
do so with caution!
## Configure it
@@ -154,12 +163,14 @@ do so with caution!
# Create directory for satellites
sudo -u git -H mkdir /home/git/gitlab-satellites
- # Create directory for pids and make sure GitLab can write to it
+ # Create directories for sockets/pids and make sure GitLab can write to them
sudo -u git -H mkdir tmp/pids/
+ sudo -u git -H mkdir tmp/sockets/
sudo chmod -R u+rwX tmp/pids/
+ sudo chmod -R u+rwX tmp/sockets/
- # Copy the example Unicorn config
- sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb
+ # Copy the example Puma config
+ sudo -u git -H cp config/puma.rb.example config/puma.rb
**Important Note:**
Make sure to edit both files to match your setup.
@@ -196,7 +207,7 @@ Make sure to update username/password in config/database.yml.
Download the init script (will be /etc/init.d/gitlab):
- sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab
+ sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/master/lib/support/init.d/gitlab
sudo chmod +x /etc/init.d/gitlab
Make GitLab start on boot:
@@ -237,7 +248,7 @@ If you can't or don't want to use Nginx as your web server, have a look at the
Download an example site config:
- sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab
+ sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlabhq/master/lib/support/nginx/gitlab
sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab
Make sure to edit the config file to match your setup:
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 9209fad571b..6b7b4bdab0b 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -45,7 +45,10 @@ We recommend a processor with **4 cores**. At a minimum you need a processor wit
## Memory
-We recommend you to run GitLab on a server with at least **1GB of RAM** memory. You can use it with 512MB of memory but you need to setup unicorn to use only 1 worker and you need at least 200MB of swap. The minimal requirement for an unmodified installation is 768MB. With 1.5GB of memory you should be able to support 1000+ users.
+- 512MB is too little memory, GitLab will be very slow you will need 250MB of swap
+- 768MB is the minimal memory size and supports up to 100 users
+- **1GB** is the **recommended** memory size and supports up to 1,000 users
+- 1.5GB supports up to 10,000 users
## Storage
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index b551470545c..338e885851d 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -11,31 +11,30 @@ Example output:
```
System information
-System: Debian 6.0.6
-Current User: gitlab
-Using RVM: yes
-RVM Version: 1.17.2
-Ruby Version: ruby-1.9.3-p392
-Gem Version: 1.8.24
-Bundler Version:1.2.3
-Rake Version: 10.0.1
+System: Debian 6.0.7
+Current User: git
+Using RVM: no
+Ruby Version: 1.9.3p392
+Gem Version: 1.8.23
+Bundler Version:1.3.5
+Rake Version: 10.0.4
GitLab information
-Version: 3.1.0
-Resivion: fd5141d
-Directory: /home/gitlab/gitlab
-DB Adapter: mysql2
-URL: http://localhost:3000
-HTTP Clone URL: http://localhost:3000/some-project.git
-SSH Clone URL: git@localhost:some-project.git
-Using LDAP: no
-Using Omniauth: no
+Version: 5.1.0.beta2
+Revision: 4da8b37
+Directory: /home/git/gitlab
+DB Adapter: mysql2
+URL: http://localhost
+HTTP Clone URL: http://localhost/some-project.git
+SSH Clone URL: git@localhost:some-project.git
+Using LDAP: no
+Using Omniauth: no
GitLab Shell
-Version: 1.0.4
-Repositories: /home/git/repositories/
-Hooks: /home/git/gitlab-shell/hooks/
-Git: /usr/bin/git
+Version: 1.2.0
+Repositories: /home/git/repositories/
+Hooks: /home/git/gitlab-shell/hooks/
+Git: /usr/bin/git
```
@@ -61,60 +60,43 @@ Example output:
```
Checking Environment ...
-gitlab user is in git group? ... yes
-Has no "-e" in ~git/.profile ... yes
-Git configured for gitlab user? ... yes
+Git configured for git user? ... yes
Has python2? ... yes
python2 is supported version? ... yes
Checking Environment ... Finished
-Checking Gitolite ...
+Checking Gitlab Shell ...
-Using recommended version ... yes
-Config directory exists? ... yes
-Config directory owned by git:git? ... yes
-Config directory access is drwxr-x---? ... yes
+GitLab Shell version? ... OK (1.2.0)
Repo base directory exists? ... yes
+Repo base directory is a symlink? ... no
Repo base owned by git:git? ... yes
Repo base access is drwxrws---? ... yes
-post-receive hook exists? ... yes
post-receive hook up-to-date? ... yes
-post-receive hooks in repos are links: ...
-GitLab ... ok
-Non-Ascii Files Test ... ok
-Touch Commit Test ... ok
-Without Master Test ... ok
-Git config in repos: ...
-GitLab ... ok
-Non-Ascii Files Test ... ok
-Touch Commit Test ... ok
-Without Master Test ... ok
+post-receive hooks in repos are links: ... yes
-Checking Gitolite ... Finished
+Checking Gitlab Shell ... Finished
-Checking Resque ...
+Checking Sidekiq ...
Running? ... yes
-Checking Resque ... Finished
+Checking Sidekiq ... Finished
Checking GitLab ...
Database config exists? ... yes
-Database is not SQLite ... yes
+Database is SQLite ... no
All migrations up? ... yes
GitLab config exists? ... yes
-GitLab config not outdated? ... yes
+GitLab config outdated? ... no
Log directory writable? ... yes
Tmp directory writable? ... yes
Init script exists? ... yes
Init script up-to-date? ... yes
-Projects have satellites? ...
-GitLab ... yes
-Non-Ascii Files Test ... yes
-Touch Commit Test ... yes
-Without Master Test ... yes
+Projects have satellites? ... yes
+Redis version >= 2.0.0? ... yes
Checking GitLab ... Finished
```
diff --git a/doc/raketasks/user_management.md b/doc/raketasks/user_management.md
index 021ce35931f..8fa2ed1311c 100644
--- a/doc/raketasks/user_management.md
+++ b/doc/raketasks/user_management.md
@@ -1,4 +1,4 @@
-### Add user to as a developer to all projects
+### Add user as a developer to all projects
```
bundle exec rake gitlab:import:user_to_projects[username@domain.tld]
diff --git a/doc/update/2.6-to-3.0.md b/doc/update/2.6-to-3.0.md
new file mode 100644
index 00000000000..d7047d8eb19
--- /dev/null
+++ b/doc/update/2.6-to-3.0.md
@@ -0,0 +1,63 @@
+# From 2.6 to 3.0
+
+### 1. Stop server & resque
+
+ sudo service gitlab stop
+
+### 2. Update code & db
+
+
+```bash
+# Get latest code
+git fetch origin
+git checkout v3.0.3
+
+
+# Install libs
+sudo -u gitlab bundle install --without development test postgres
+
+# update db
+sudo -u gitlab bundle exec rake db:migrate RAILS_ENV=production
+
+# !!! Config should be replaced with a new one. Check it after replace
+cp config/gitlab.yml.example config/gitlab.yml
+
+# update gitolite hooks
+
+# GITOLITE v2:
+sudo cp ./lib/hooks/post-receive /home/git/share/gitolite/hooks/common/post-receive
+sudo chown git:git /home/git/share/gitolite/hooks/common/post-receive
+
+# GITOLITE v3:
+sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive
+sudo chown git:git /home/git/.gitolite/hooks/common/post-receive
+
+# set valid path to hooks in gitlab.yml in git_host section
+# like this
+git_host:
+ # gitolite 2
+ hooks_path: /home/git/share/gitolite/hooks
+ # gitolite 3
+ hooks_path: /home/git/.gitolite/hooks/
+
+
+# Make some changes to gitolite config
+# For more information visit https://github.com/gitlabhq/gitlabhq/pull/1719
+
+# gitolite v2
+sudo -u git -H sed -i 's/\(GL_GITCONFIG_KEYS\s*=>*\s*\).\{2\}/\\1"\.\*"/g' /home/git/.gitolite.rc
+
+# gitlite v3
+sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\\1'\.\*'/g" /home/git/.gitolite.rc
+
+
+# Check app status
+sudo -u gitlab bundle exec rake gitlab:app:status RAILS_ENV=production
+
+
+```
+
+
+### 3. Start all
+
+ sudo service gitlab start
diff --git a/doc/update/2.9-to-3.0.md b/doc/update/2.9-to-3.0.md
new file mode 100644
index 00000000000..af929e027a4
--- /dev/null
+++ b/doc/update/2.9-to-3.0.md
@@ -0,0 +1,37 @@
+# From 2.9 to 3.0
+
+### 1. Stop server & resque
+
+ sudo service gitlab stop
+
+### 2. Follow instructions
+
+```bash
+
+# Get latest code
+sudo -u gitlab -H git fetch origin
+sudo -u gitlab -H git checkout v3.0.3
+
+# Install gems
+sudo -u gitlab -H bundle install --without development test postgres
+
+# Migrate db
+sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production
+
+# Make some changes to gitolite v3 config
+# For more information visit https://github.com/gitlabhq/gitlabhq/pull/1719
+
+# Gitolite version 3
+sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\\1'\.\*'/g" /home/git/.gitolite.rc
+
+# If you still use gitolite v2
+sudo -u git -H sed -i 's/\(GL_GITCONFIG_KEYS\s*=>*\s*\).\{2\}/\\1"\.\*"/g' /home/git/.gitolite.rc
+
+# Check APP Status
+sudo -u gitlab -H bundle exec rake gitlab:app:status RAILS_ENV=production
+```
+
+
+### 3. Start all
+
+ sudo service gitlab start
diff --git a/doc/update/3.0-to-3.1.md b/doc/update/3.0-to-3.1.md
new file mode 100644
index 00000000000..5f06f818d10
--- /dev/null
+++ b/doc/update/3.0-to-3.1.md
@@ -0,0 +1,108 @@
+# From 3.0 to 3.1
+
+__IMPORTANT!__
+
+In this release __we moved Resque jobs under own gitlab namespace__.
+
+Despite a lot of advantages it requires from our users to __replace gitolite post-receive hook with new one__.
+
+Most of projects has post-receive file as symlink to gitolite `/home/git/.gitolite/hooks/post-receive`.
+But some of them may have a real file. In this case you should rewrite it with symlink to gitolite hook.
+
+I wrote a bash script which will do it automatically for you. Just make sure all path inside is valid for you
+
+- - -
+
+### 1. Stop server & resque
+
+ sudo service gitlab stop
+
+### 2. Update GitLab
+
+```bash
+
+# Get latest code
+sudo -u gitlab -H git fetch
+sudo -u gitlab -H git checkout v3.1.0
+
+# Install new charlock_holmes
+sudo gem install charlock_holmes --version '0.6.9'
+
+# Install gems for MySQL
+sudo -u gitlab -H bundle install --without development test postgres sqlite
+
+
+# Migrate db
+sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production
+
+
+```
+
+### 3. Update post-receive hooks
+
+#### Gitolite 3
+
+Step 1: Rewrite post-receive hook
+
+```bash
+# Rewrite hook for gitolite 3
+sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive
+sudo chown git:git /home/git/.gitolite/hooks/common/post-receive
+```
+
+Step 2: Rewrite hooks in all projects to symlink gitolite hook
+
+```bash
+# 1. Check for valid path
+sudo -u gitlab -H vim lib/support/rewrite-hooks.sh
+
+# 2. Run script
+sudo -u git -H lib/support/rewrite-hooks.sh
+```
+
+#### Gitolite v2
+
+Step 1: rewrite post-receive hook for gitolite 2
+
+```
+sudo cp ./lib/hooks/post-receive /home/git/share/gitolite/hooks/common/post-receive
+sudo chown git:git /home/git/share/gitolite/hooks/common/post-receive
+```
+
+Step 2: Replace symlinks in project to valid place
+
+
+ #!/bin/bash
+ src="/home/git/repositories"
+ for dir in `ls "$src/"`
+ do
+ if [ -d "$src/$dir" ]; then
+
+ if [ "$dir" = "gitolite-admin.git" ]
+ then
+ continue
+ fi
+
+ project_hook="$src/$dir/hooks/post-receive"
+ gitolite_hook="/home/git/share/gitolite/hooks/common/post-receive"
+
+ ln -s -f $gitolite_hook $project_hook
+ fi
+ done
+
+
+### 4. Check app status
+
+```bash
+
+# Check APP Status
+sudo -u gitlab -H bundle exec rake gitlab:app:status RAILS_ENV=production
+
+
+
+```
+
+
+### 5. Start all
+
+ sudo service gitlab start
diff --git a/doc/update/3.1-to-4.0.md b/doc/update/3.1-to-4.0.md
new file mode 100644
index 00000000000..c5ae3a40a76
--- /dev/null
+++ b/doc/update/3.1-to-4.0.md
@@ -0,0 +1,99 @@
+# From 3.1 to 4.0
+
+## Important changes
+
+* Support for SQLite was dropped
+* Support for gitolite 2 was dropped
+* Projects are organized in namespaces
+* The GitLab post-receive hook needs to be updated
+* The configuration file needs to be updated
+* Availability of `python2` executable
+
+Most of projects has post-receive file as symlink to gitolite `/home/git/.gitolite/hooks/post-receive`.
+But some of them may have a real file. In this case you should rewrite it with symlink to gitolite hook.
+
+I wrote a bash script which will do it automatically for you. Just make sure all path inside is valid for you
+
+- - -
+
+### 1. Stop GitLab & Resque
+
+ sudo service gitlab stop
+
+### 2. Update GitLab
+
+```bash
+
+# Get latest code
+sudo -u gitlab -H git fetch
+sudo -u gitlab -H git checkout 4-0-stable
+
+# Install gems for MySQL
+sudo -u gitlab -H bundle install --without development test postgres
+
+# Update repos permissions
+sudo chmod -R ug+rwXs /home/git/repositories/
+sudo chown -R git:git /home/git/repositories/
+
+# Migrate db
+sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production
+
+# Enable namespaces (**Warning!** All projects in groups will be moved to subdirectories)
+sudo -u gitlab -H bundle exec rake gitlab:enable_namespaces RAILS_ENV=production
+
+```
+
+### 3. Update post-receive hooks (Requires gitolite v3 )
+
+
+Step 1: Rewrite post-receive hook
+
+```bash
+sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive
+sudo chown git:git /home/git/.gitolite/hooks/common/post-receive
+```
+
+Step 2: Update project hooks to be symlinks to the Gitolite hook
+
+```bash
+# 1. Check paths in script
+sudo -u gitlab -H vim lib/support/rewrite-hooks.sh
+
+# 2. Run script
+sudo -u git -H lib/support/rewrite-hooks.sh
+```
+
+
+### 4. Replace config with new one
+
+
+ # backup old one
+ sudo -u gitlab -H cp config/gitlab.yml config/gitlab.yml.old
+
+ # copy new one
+ sudo -u gitlab -H cp config/gitlab.yml.example config/gitlab.yml
+
+ # edit it
+ sudo -u gitlab -H vim config/gitlab.yml
+
+
+### 5. Disable ssh known_host check for own domain
+
+
+ echo "Host localhost
+ StrictHostKeyChecking no
+ UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config
+
+ echo "Host YOUR_DOMAIN_NAME
+ StrictHostKeyChecking no
+ UserKnownHostsFile=/dev/null" | sudo tee -a /etc/ssh/ssh_config
+
+
+### 6. Check GitLab's status
+
+ sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
+
+
+### 7. Start GitLab & Resque
+
+ sudo service gitlab start
diff --git a/doc/update/4.0-to-4.1.md b/doc/update/4.0-to-4.1.md
new file mode 100644
index 00000000000..368351d0c91
--- /dev/null
+++ b/doc/update/4.0-to-4.1.md
@@ -0,0 +1,55 @@
+# From 4.0 to 4.1
+
+## Important changes
+
+* Resque replaced with Sidekiq
+* New options for configuration file added
+* Init.d script should be updated
+* __requires ruby1.9.3-p327__
+
+- - -
+
+### 1. Stop GitLab & Resque
+
+ sudo service gitlab stop
+
+### 2. Update GitLab
+
+```bash
+
+# Get latest code
+sudo -u gitlab -H git fetch
+sudo -u gitlab -H git checkout 4-1-stable
+
+# Install gems for MySQL
+sudo -u gitlab -H bundle install --without development test postgres
+
+# Migrate db
+sudo -u gitlab -H bundle exec rake db:migrate RAILS_ENV=production
+
+```
+
+### 3. Replace init.d script with a new one
+
+```
+# backup old one
+sudo mv /etc/init.d/gitlab /etc/init.d/gitlab.old
+
+# get new one usign sidekiq
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/4-1-stable/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+
+```
+
+### 4. Check GitLab's status
+
+ sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
+
+
+### 5. Start GitLab & Sidekiq
+
+ sudo service gitlab start
+
+### 6. Remove old init.d script
+
+ sudo rm /etc/init.d/gitlab.old
diff --git a/doc/update/4.1-to-4.2.md b/doc/update/4.1-to-4.2.md
new file mode 100644
index 00000000000..15fea593560
--- /dev/null
+++ b/doc/update/4.1-to-4.2.md
@@ -0,0 +1,34 @@
+# From 4.1 to 4.2
+
+### 1. Stop server & resque
+
+ sudo service gitlab stop
+
+### 2. Update code & db
+
+```bash
+# Get latest code
+sudo -u gitlab git fetch
+
+sudo -u gitlab git checkout 4-2-stable
+
+# Install libs
+sudo -u gitlab bundle install --without development test postgres --deployment
+
+# update db
+sudo -u gitlab bundle exec rake db:migrate RAILS_ENV=production
+
+```
+
+
+### 3. Check GitLab's status
+
+```bash
+sudo -u gitlab -H bundle exec rake gitlab:check RAILS_ENV=production
+```
+
+
+
+### 4. Start all
+
+ sudo service gitlab start
diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md
new file mode 100644
index 00000000000..408e4ed3d0f
--- /dev/null
+++ b/doc/update/4.2-to-5.0.md
@@ -0,0 +1,163 @@
+# From 4.2 to 5.0
+
+## Important changes
+
+* We dont use `gitlab` user any more. Everything will be moved to `git` user
+* __requires ruby1.9.3__
+
+
+__0. Stop gitlab__
+
+ sudo service gitlab stop
+
+__1. add bash to git user__
+
+```
+sudo chsh -s /bin/bash git
+```
+
+__2. git clone gitlab-shell__
+
+```
+sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git /home/git/gitlab-shell
+```
+
+__3. setup gitlab-shell__
+
+```bash
+# chmod all repos and files under git
+sudo chown git:git -R /home/git/repositories/
+
+# login as git
+sudo su git
+cd /home/git/gitlab-shell
+
+# copy config
+cp config.yml.example config.yml
+
+# change url to gitlab instance
+# ! make sure url end with '/' like 'https://gitlab.example/'
+vim config.yml
+
+# rewrite hooks
+./support/rewrite-hooks.sh
+
+# check ruby version for git user ( 1.9 required!! )
+# gitlab shell requires system ruby 1.9
+ruby -v
+
+# exit from git user
+exit
+```
+
+__4. Copy gitlab instance to git user__
+
+```bash
+sudo cp -R /home/gitlab/gitlab /home/git/gitlab
+sudo chown git:git -R /home/git/gitlab
+sudo rm -rf /home/gitlab/gitlab-satellites
+
+# if exists
+sudo rm /tmp/gitlab.socket
+```
+
+__5. Update gitlab to recent version__
+
+```bash
+cd /home/git/gitlab
+
+# backup current config
+sudo -u git -H cp config/gitlab.yml config/gitlab.yml.old
+
+sudo -u git -H git fetch
+sudo -u git -H git checkout 5-0-stable
+
+# replace config with recent one
+sudo -u git -H cp config/gitlab.yml.example config/gitlab.yml
+
+# edit it
+sudo -u git -H vim config/gitlab.yml
+
+
+sudo -u git -H bundle install --without development test postgres --deployment
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+sudo -u git -H bundle exec rake gitlab:shell:setup RAILS_ENV=production
+sudo -u git -H bundle exec rake gitlab:shell:build_missing_projects RAILS_ENV=production
+
+sudo -u git -H mkdir /home/git/gitlab-satellites
+sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production
+
+# migrate wiki to git
+sudo -u git -H bundle exec rake gitlab:wiki:migrate RAILS_ENV=production
+
+
+# check permissions for /home/git/.ssh/
+sudo -u git -H chmod 700 /home/git/.ssh
+sudo -u git -H chmod 600 /home/git/.ssh/authorized_keys
+
+# check permissions for /home/git/gitlab/
+sudo chown -R git /home/git/gitlab/log/
+sudo chown -R git /home/git/gitlab/tmp/
+sudo chmod -R u+rwX /home/git/gitlab/log/
+sudo chmod -R u+rwX /home/git/gitlab/tmp/
+sudo -u git -H mkdir /home/git/gitlab/tmp/pids/
+sudo chmod -R u+rwX /home/git/gitlab/tmp/pids
+
+```
+
+__6. Update init.d script and nginx config__
+
+```bash
+# init.d
+sudo rm /etc/init.d/gitlab
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-0-stable/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+
+# unicorn
+sudo -u git -H cp /home/git/gitlab/config/unicorn.rb /home/git/gitlab/config/unicorn.rb.old
+sudo -u git -H cp /home/git/gitlab/config/unicorn.rb.example /home/git/gitlab/config/unicorn.rb
+
+#nginx
+# Replace path from '/home/gitlab/' to '/home/git/'
+sudo vim /etc/nginx/sites-enabled/gitlab
+sudo service nginx restart
+
+
+```
+
+__7. Start gitlab instace__
+
+```
+
+
+sudo service gitlab start
+
+# check if unicorn and sidekiq started
+# If not try to logout, also check replaced path from '/home/gitlab/' to '/home/git/'
+# in nginx, unicorn, init.d etc
+ps aux | grep unicorn
+ps aux | grep sidekiq
+
+```
+
+__8. Check installation__
+
+
+```bash
+# In 5-10 seconds lets check gitlab-shell
+sudo -u git -H /home/git/gitlab-shell/bin/check
+
+# Example of success output
+# Check GitLab API access: OK
+# Check directories and files:
+# /home/git/repositories: OK
+# /home/git/.ssh/authorized_keys: OK
+
+
+# Now check gitlab instance
+sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+
+```
+
+
+__P.S. If everything works as expected you can remove gitlab user from system__
diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md
new file mode 100644
index 00000000000..25fe2f50e25
--- /dev/null
+++ b/doc/update/5.0-to-5.1.md
@@ -0,0 +1,61 @@
+# From 5.0 to 5.1
+
+## Release notes:
+
+* `unicorn` replaced with `puma`
+* merge request cached diff will be truncated
+
+### 1. Stop server
+
+ sudo service gitlab stop
+
+### 2. Get latest code
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H git fetch
+sudo -u git -H git checkout 5-1-stable
+```
+
+### 3. Update gitlab-shell
+
+```bash
+cd /home/git/gitlab-shell
+sudo -u git -H git fetch
+sudo -u git -H git checkout v1.3.0
+```
+
+### 4. Install libs, migrations etc
+
+```bash
+cd /home/git/gitlab
+sudo rm tmp/sockets/gitlab.socket
+sudo -u git -H cp config/puma.rb.example config/puma.rb
+
+sudo -u git -H bundle install --without development test postgres --deployment
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+sudo -u git -H bundle exec rake migrate_merge_requests RAILS_ENV=production
+```
+
+### 5. Update init.d script with a new one
+
+```bash
+# init.d
+sudo rm /etc/init.d/gitlab
+sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlab-recipes/5-1-stable/init.d/gitlab
+sudo chmod +x /etc/init.d/gitlab
+```
+
+### 6. Mysql grant privileges
+
+Only if you are using mysql:
+
+```bash
+mysql -u root -p
+mysql> GRANT LOCK TABLES ON `gitlabhq_production`.* TO 'gitlab'@'localhost';
+mysql> \q
+```
+
+### 7. Start application
+
+ sudo service gitlab start
diff --git a/features/project/network.feature b/features/project/network.feature
index a6cbd2c4781..538124a4c5f 100644
--- a/features/project/network.feature
+++ b/features/project/network.feature
@@ -11,14 +11,16 @@ Feature: Project Network Graph
And page should have "master" on graph
@javascript
- Scenario: I should switch ref to "stable"
+ Scenario: I should switch "branch" and "tag"
When I switch ref to "stable"
- Then page should have network graph
- And page should select "stable" in select box
+ Then page should select "stable" in select box
And page should have "stable" on graph
+ When I switch ref to "v2.1.0"
+ Then page should select "v2.1.0" in select box
+ And page should have "v2.1.0" on graph
@javascript
- Scenario: I should looking for a commit by SHA of "v2.1.0"
+ Scenario: I should looking for a commit by SHA
When I looking for a commit by SHA of "v2.1.0"
Then page should have network graph
And page should select "master" in select box
diff --git a/features/project/team_management.feature b/features/project/team_management.feature
index 04545a08e0a..fc353424e36 100644
--- a/features/project/team_management.feature
+++ b/features/project/team_management.feature
@@ -21,7 +21,6 @@ Feature: Project Team management
Scenario: Update user access
Given I should see "Sam" in team list as "Developer"
And I change "Sam" role to "Reporter"
- Then I visit project "Shop" team page
And I should see "Sam" in team list as "Reporter"
Scenario: Cancel team member
diff --git a/features/steps/project/project_network_graph.rb b/features/steps/project/project_network_graph.rb
index cf5fa751ccf..763b4de2abc 100644
--- a/features/steps/project/project_network_graph.rb
+++ b/features/steps/project/project_network_graph.rb
@@ -30,10 +30,19 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
sleep 2
end
+ When 'I switch ref to "v2.1.0"' do
+ page.select 'v2.1.0', :from => 'ref'
+ sleep 2
+ end
+
And 'page should select "stable" in select box' do
page.should have_selector '#ref_chzn span', :text => "stable"
end
+ And 'page should select "v2.1.0" in select box' do
+ page.should have_selector '#ref_chzn span', :text => "v2.1.0"
+ end
+
And 'page should have "stable" on graph' do
within '.graph' do
page.should have_content 'stable'
diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb
index 96bf0df2899..ffd2aa24676 100644
--- a/features/steps/project/project_team_management.rb
+++ b/features/steps/project/project_team_management.rb
@@ -30,15 +30,15 @@ class ProjectTeamManagement < Spinach::FeatureSteps
end
Then 'I should see "Mike" in team list as "Reporter"' do
- user = User.find_by_name("Mike")
- role_id = find(".user_#{user.id} #team_member_project_access").value
- role_id.should == UsersProject.access_roles["Reporter"].to_s
+ within '.reporters' do
+ page.should have_content('Mike')
+ end
end
Given 'I should see "Sam" in team list as "Developer"' do
- user = User.find_by_name("Sam")
- role_id = find(".user_#{user.id} #team_member_project_access").value
- role_id.should == UsersProject.access_roles["Developer"].to_s
+ within '.developers' do
+ page.should have_content('Sam')
+ end
end
And 'I change "Sam" role to "Reporter"' do
@@ -49,9 +49,9 @@ class ProjectTeamManagement < Spinach::FeatureSteps
end
And 'I should see "Sam" in team list as "Reporter"' do
- user = User.find_by_name("Sam")
- role_id = find(".user_#{user.id} #team_member_project_access").value
- role_id.should == UsersProject.access_roles["Reporter"].to_s
+ within '.reporters' do
+ page.should have_content('Sam')
+ end
end
And 'I click link "Remove from team"' do
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index 81451638090..affe1be54dd 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -22,6 +22,7 @@ module Gitlab
key = Key.find(params[:key_id])
project = Project.find_with_namespace(project_path)
git_cmd = params[:action]
+ return false unless project
if key.is_deploy_key
@@ -32,7 +33,7 @@ module Gitlab
return false if user.blocked?
action = case git_cmd
- when 'git-upload-pack'
+ when 'git-upload-pack', 'git-upload-archive'
then :download_code
when 'git-receive-pack'
then
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 125a8624021..4198387d403 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -12,6 +12,7 @@ module Gitlab
@users = User.scoped
@users = @users.active if params[:active].present?
@users = @users.search(params[:search]) if params[:search].present?
+ @users = paginate @users
present @users, with: Entities::User
end
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 009c5fcada9..1b7c698d0a8 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -98,9 +98,7 @@ module ExtractsPath
@ref, @path = extract_ref(@id)
- # It is used "@project.repository.commits(@ref, @path, 1, 0)",
- # because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name.
- @commit = @project.repository.commits(@ref, @path, 1, 0).first
+ @commit = @project.repository.commit(@ref)
@tree = Tree.new(@project.repository, @commit.id, @ref, @path)
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index abbee6132d3..6a411aabcc6 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -1,4 +1,5 @@
require_relative 'shell_env'
+require 'omniauth-ldap'
module Grack
class Auth < Rack::Auth::Basic
@@ -32,8 +33,18 @@ module Grack
# Authentication with username and password
login, password = @auth.credentials
self.user = User.find_by_email(login) || User.find_by_username(login)
- return false unless user.try(:valid_password?, password)
+ # If the provided login was not a known email or username
+ # then user is nil
+ if user.nil?
+ # Second chance - try LDAP authentication
+ return false unless Gitlab.config.ldap.enabled
+ ldap_auth(login,password)
+ return false unless !user.nil?
+ else
+ return false unless user.valid_password?(password)
+ end
+
Gitlab::ShellEnv.set_env(user)
end
@@ -47,14 +58,35 @@ module Grack
end
end
+ def ldap_auth(login, password)
+ # Check user against LDAP backend if user is not authenticated
+ # Only check with valid login and password to prevent anonymous bind results
+ gl = Gitlab.config
+ if gl.ldap.enabled && !login.blank? && !password.blank?
+ ldap = OmniAuth::LDAP::Adaptor.new(gl.ldap)
+ ldap_user = ldap.bind_as(
+ filter: Net::LDAP::Filter.eq(ldap.uid, login),
+ size: 1,
+ password: password
+ )
+ if ldap_user
+ self.user = User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap')
+ end
+ end
+ end
+
def validate_get_request
- project.public || can?(user, :download_code, project)
+ validate_request(@request.params['service'])
end
def validate_post_request
- if @request.path_info.end_with?('git-upload-pack')
+ validate_request(File.basename(@request.path))
+ end
+
+ def validate_request(service)
+ if service == 'git-upload-pack'
project.public || can?(user, :download_code, project)
- elsif @request.path_info.end_with?('git-receive-pack')
+ elsif service == 'git-receive-pack'
action = if project.protected_branch?(current_ref)
:push_code_to_protected_branches
else
@@ -79,7 +111,7 @@ module Grack
end
# Need to reset seek point
@request.body.rewind
- /refs\/heads\/([\w\.-]+)/.match(input).to_a.last
+ /refs\/heads\/([\w\.-]+)/n.match(input.force_encoding('ascii-8bit')).to_a.last
end
def project
diff --git a/lib/gitlab/git/blame.rb b/lib/gitlab/git/blame.rb
deleted file mode 100644
index d6e988b6762..00000000000
--- a/lib/gitlab/git/blame.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-module Gitlab
- module Git
- class Blame
-
- attr_accessor :repository, :sha, :path
-
- def initialize(repository, sha, path)
- @repository, @sha, @path = repository, sha, path
-
- end
-
- def each
- raw_blame = Grit::Blob.blame(repository.repo, sha, path)
-
- raw_blame.each do |commit, lines|
- commit = Gitlab::Git::Commit.new(commit)
- yield(commit, lines)
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/git/blob.rb b/lib/gitlab/git/blob.rb
deleted file mode 100644
index 57b89912f2d..00000000000
--- a/lib/gitlab/git/blob.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-module Gitlab
- module Git
- class Blob
- include Linguist::BlobHelper
-
- attr_accessor :raw_blob
-
- delegate :name, to: :raw_blob
-
- def initialize(repository, sha, ref, path)
- @repository, @sha, @ref = repository, sha, ref
-
- @commit = @repository.commit(sha)
- @raw_blob = @repository.tree(@commit, path)
- end
-
- def data
- if raw_blob
- raw_blob.data
- else
- nil
- end
- end
-
- def exists?
- raw_blob
- end
-
- def empty?
- data.blank?
- end
-
- def mode
- raw_blob.mode
- end
-
- def size
- raw_blob.size
- end
- end
- end
-end
diff --git a/lib/gitlab/git/commit.rb b/lib/gitlab/git/commit.rb
deleted file mode 100644
index 27b866893f9..00000000000
--- a/lib/gitlab/git/commit.rb
+++ /dev/null
@@ -1,121 +0,0 @@
-# Gitlab::Git::Commit is a wrapper around native Grit::Commit object
-# We dont want to use grit objects inside app/
-# It helps us easily migrate to rugged in future
-module Gitlab
- module Git
- class Commit
- attr_accessor :raw_commit, :head, :refs,
- :id, :authored_date, :committed_date, :message,
- :author_name, :author_email, :parent_ids,
- :committer_name, :committer_email
-
- delegate :parents, :diffs, :tree, :stats, :to_patch,
- to: :raw_commit
-
- def initialize(raw_commit, head = nil)
- raise "Nil as raw commit passed" unless raw_commit
-
- if raw_commit.is_a?(Hash)
- init_from_hash(raw_commit)
- else
- init_from_grit(raw_commit)
- end
-
- @head = head
- end
-
- def serialize_keys
- %w(id authored_date committed_date author_name author_email committer_name committer_email message parent_ids)
- end
-
- def sha
- id
- end
-
- def short_id(length = 10)
- id.to_s[0..length]
- end
-
- def safe_message
- @safe_message ||= message
- end
-
- def created_at
- committed_date
- end
-
- # Was this commit committed by a different person than the original author?
- def different_committer?
- author_name != committer_name || author_email != committer_email
- end
-
- def parent_id
- parent_ids.first
- end
-
- # Shows the diff between the commit's parent and the commit.
- #
- # Cuts out the header and stats from #to_patch and returns only the diff.
- def to_diff
- # see Grit::Commit#show
- patch = to_patch
-
- # discard lines before the diff
- lines = patch.split("\n")
- while !lines.first.start_with?("diff --git") do
- lines.shift
- end
- lines.pop if lines.last =~ /^[\d.]+$/ # Git version
- lines.pop if lines.last == "-- " # end of diff
- lines.join("\n")
- end
-
- def has_zero_stats?
- stats.total.zero?
- rescue
- true
- end
-
- def no_commit_message
- "--no commit message"
- end
-
- def to_hash
- hash = {}
-
- keys = serialize_keys
-
- keys.each do |key|
- hash[key] = send(key)
- end
-
- hash
- end
-
- def date
- committed_date
- end
-
- private
-
- def init_from_grit(grit)
- @raw_commit = grit
- @id = grit.id
- @message = grit.message
- @authored_date = grit.authored_date
- @committed_date = grit.committed_date
- @author_name = grit.author.name
- @author_email = grit.author.email
- @committer_name = grit.committer.name
- @committer_email = grit.committer.email
- @parent_ids = grit.parents.map(&:id)
- end
-
- def init_from_hash(hash)
- serialize_keys.each do |key|
- send(:"#{key}=", hash[key])
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/git/compare.rb b/lib/gitlab/git/compare.rb
deleted file mode 100644
index e34f204e8bd..00000000000
--- a/lib/gitlab/git/compare.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-module Gitlab
- module Git
- class Compare
- attr_accessor :commits, :commit, :diffs, :same
-
- def initialize(repository, from, to)
- @commits, @diffs = [], []
- @commit = nil
- @same = false
-
- return unless from && to
-
- first = repository.commit(to.try(:strip))
- last = repository.commit(from.try(:strip))
-
- return unless first && last
-
- if first.id == last.id
- @same = true
- return
- end
-
- @commit = first
- @commits = repository.commits_between(last.id, first.id)
-
- @diffs = if @commits.size > 100
- []
- else
- repository.repo.diff(last.id, first.id) rescue []
- end
- end
- end
- end
-end
-
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
deleted file mode 100644
index 6d4e9e8491f..00000000000
--- a/lib/gitlab/git/repository.rb
+++ /dev/null
@@ -1,201 +0,0 @@
-# Gitlab::Git::Gitlab::Git::Commit is a wrapper around native Grit::Repository object
-# We dont want to use grit objects inside app/
-# It helps us easily migrate to rugged in future
-module Gitlab
- module Git
- class Repository
- include Gitlab::Popen
-
- class NoRepository < StandardError; end
-
- # Repository directory name with namespace direcotry
- # Examples:
- # gitlab/gitolite
- # diaspora
- #
- attr_accessor :path_with_namespace
-
- # Grit repo object
- attr_accessor :repo
-
- # Default branch in the repository
- attr_accessor :root_ref
-
- def initialize(path_with_namespace, root_ref = 'master')
- @root_ref = root_ref || "master"
- @path_with_namespace = path_with_namespace
-
- # Init grit repo object
- repo
- end
-
- def raw
- repo
- end
-
- def path_to_repo
- @path_to_repo ||= File.join(repos_path, "#{path_with_namespace}.git")
- end
-
- def repos_path
- Gitlab.config.gitlab_shell.repos_path
- end
-
- def repo
- @repo ||= Grit::Repo.new(path_to_repo)
- rescue Grit::NoSuchPathError
- raise NoRepository.new('no repository for such path')
- end
-
- def commit(commit_id = nil)
- commit = if commit_id
- repo.commit(commit_id)
- else
- repo.commits(root_ref).first
- end
-
- decorate_commit(commit) if commit
- end
-
- def commits_with_refs(n = 20)
- commits = repo.branches.map { |ref| decorate_commit(ref.commit, ref) }
-
- commits.sort! do |x, y|
- y.committed_date <=> x.committed_date
- end
-
- commits[0..n]
- end
-
- def commits(ref, path = nil, limit = nil, offset = nil)
- if path
- repo.log(ref, path, max_count: limit, skip: offset)
- elsif limit && offset
- repo.commits(ref, limit, offset)
- else
- repo.commits(ref)
- end.map{ |c| decorate_commit(c) }
- end
-
- def commits_between(from, to)
- repo.commits_between(from, to).map { |c| decorate_commit(c) }
- end
-
- def last_commit_for(ref, path = nil)
- commits(ref, path, 1).first
- end
-
- # Returns an Array of branch names
- # sorted by name ASC
- def branch_names
- branches.map(&:name)
- end
-
- # Returns an Array of Branches
- def branches
- repo.branches.sort_by(&:name)
- end
-
- # Returns an Array of tag names
- def tag_names
- repo.tags.collect(&:name).sort.reverse
- end
-
- # Returns an Array of Tags
- def tags
- repo.tags.sort_by(&:name).reverse
- end
-
- # Returns an Array of branch and tag names
- def ref_names
- [branch_names + tag_names].flatten
- end
-
- def heads
- @heads ||= repo.heads
- end
-
- def tree(fcommit, path = nil)
- fcommit = commit if fcommit == :head
- tree = fcommit.tree
- path ? (tree / path) : tree
- end
-
- def has_commits?
- !!commit
- rescue Grit::NoSuchPathError
- false
- end
-
- def empty?
- !has_commits?
- end
-
- # Discovers the default branch based on the repository's available branches
- #
- # - If no branches are present, returns nil
- # - If one branch is present, returns its name
- # - If two or more branches are present, returns the one that has a name
- # matching root_ref (default_branch or 'master' if default_branch is nil)
- def discover_default_branch
- if branch_names.length == 0
- nil
- elsif branch_names.length == 1
- branch_names.first
- else
- branch_names.select { |v| v == root_ref }.first
- end
- end
-
- # Archive Project to .tar.gz
- #
- # Already packed repo archives stored at
- # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
- #
- def archive_repo(ref)
- ref = ref || self.root_ref
- commit = self.commit(ref)
- return nil unless commit
-
- # Build file path
- file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
- storage_path = Rails.root.join("tmp", "repositories")
- file_path = File.join(storage_path, self.path_with_namespace, file_name)
-
- # Put files into a directory before archiving
- prefix = File.basename(self.path_with_namespace) + "/"
-
- # Create file if not exists
- unless File.exists?(file_path)
- FileUtils.mkdir_p File.dirname(file_path)
- file = self.repo.archive_to_file(ref, prefix, file_path)
- end
-
- file_path
- end
-
- # Return repo size in megabytes
- # Cached in redis
- def size
- Rails.cache.fetch(cache_key(:size)) do
- size = popen('du -s', path_to_repo).first.strip.to_i
- (size.to_f / 1024).round(2)
- end
- end
-
- def expire_cache
- Rails.cache.delete(cache_key(:size))
- end
-
- def cache_key(type)
- "#{type}:#{path_with_namespace}"
- end
-
- protected
-
- def decorate_commit(commit, ref = nil)
- Gitlab::Git::Commit.new(commit, ref)
- end
- end
- end
-end
diff --git a/lib/gitlab/git/stats.rb b/lib/gitlab/git/stats.rb
deleted file mode 100644
index c925c653342..00000000000
--- a/lib/gitlab/git/stats.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-module Gitlab
- module Git
- class Stats
- attr_accessor :repo, :ref
-
- def initialize repo, ref
- @repo, @ref = repo, ref
- end
-
- def authors
- @authors ||= collect_authors
- end
-
- def commits_count
- @commits_count ||= repo.commit_count(ref)
- end
-
- def files_count
- args = [ref, '-r', '--name-only' ]
- repo.git.run(nil, 'ls-tree', nil, {}, args).split("\n").count
- end
-
- def authors_count
- authors.size
- end
-
- def graph
- @graph ||= build_graph
- end
-
- protected
-
- def collect_authors
- shortlog = repo.git.shortlog({e: true, s: true }, ref)
-
- authors = []
-
- lines = shortlog.split("\n")
-
- lines.each do |line|
- data = line.split("\t")
- commits = data.first
- author = Grit::Actor.from_string(data.last)
-
- authors << OpenStruct.new(
- name: author.name,
- email: author.email,
- commits: commits.to_i
- )
- end
-
- authors.sort_by(&:commits).reverse
- end
-
- def build_graph n = 4
- from, to = (Date.today - n.weeks), Date.today
- args = ['--all', "--since=#{from.to_s(:date)}", '--format=%ad' ]
- rev_list = repo.git.run(nil, 'rev-list', nil, {}, args).split("\n")
-
- commits_dates = rev_list.values_at(* rev_list.each_index.select {|i| i.odd?})
- commits_dates = commits_dates.map { |date_str| Time.parse(date_str).to_date.to_s(:date) }
-
- commits_per_day = from.upto(to).map do |day|
- commits_dates.count(day.to_date.to_s(:date))
- end
-
- OpenStruct.new(
- labels: from.upto(to).map { |day| day.stamp('Aug 23') },
- commits: commits_per_day,
- weeks: n
- )
- end
- end
- end
-end
diff --git a/lib/gitlab/git/tree.rb b/lib/gitlab/git/tree.rb
deleted file mode 100644
index e6b500ba18c..00000000000
--- a/lib/gitlab/git/tree.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-module Gitlab
- module Git
- class Tree
- attr_accessor :repository, :sha, :path, :ref, :raw_tree, :id
-
- def initialize(repository, sha, ref = nil, path = nil)
- @repository, @sha, @ref, @path = repository, sha, ref, path
-
- @path = nil if @path.blank?
-
- # Load tree from repository
- @commit = @repository.commit(@sha)
- @raw_tree = @repository.tree(@commit, @path)
- end
-
- def exists?
- raw_tree
- end
-
- def empty?
- data.blank?
- end
-
- def trees
- entries.select { |t| t.is_a?(Grit::Tree) }
- end
-
- def blobs
- entries.select { |t| t.is_a?(Grit::Blob) }
- end
-
- def is_blob?
- raw_tree.is_a?(Grit::Blob)
- end
-
- def up_dir?
- path.present?
- end
-
- def readme
- @readme ||= blobs.find { |c| c.name =~ /^readme/i }
- end
-
- protected
-
- def entries
- raw_tree.contents
- end
- end
- end
-end
-
diff --git a/lib/gitlab/identifier.rb b/lib/gitlab/identifier.rb
new file mode 100644
index 00000000000..a1ff248a77f
--- /dev/null
+++ b/lib/gitlab/identifier.rb
@@ -0,0 +1,23 @@
+# Detect user based on identifier like
+# key-13 or user-36 or last commit
+module Gitlab
+ module Identifier
+ def identify(identifier, project, newrev)
+ if identifier.blank?
+ # Local push from gitlab
+ email = project.repository.commit(newrev).author_email rescue nil
+ User.find_by_email(email) if email
+
+ elsif identifier =~ /\Auser-\d+\Z/
+ # git push over http
+ user_id = identifier.gsub("user-", "")
+ User.find_by_id(user_id)
+
+ elsif identifier =~ /\Akey-\d+\Z/
+ # git push over ssh
+ key_id = identifier.gsub("key-", "")
+ Key.find_by_id(key_id).try(:user)
+ end
+ end
+ end
+end
diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab
new file mode 100644
index 00000000000..93321d6440f
--- /dev/null
+++ b/lib/support/init.d/gitlab
@@ -0,0 +1,131 @@
+#! /bin/bash
+
+# GITLAB
+# Maintainer: @randx
+# App Version: 5.1
+
+### BEGIN INIT INFO
+# Provides: gitlab
+# Required-Start: $local_fs $remote_fs $network $syslog redis-server
+# Required-Stop: $local_fs $remote_fs $network $syslog
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: GitLab git repository management
+# Description: GitLab git repository management
+### END INIT INFO
+
+
+APP_ROOT="/home/git/gitlab"
+DAEMON_OPTS="-C $APP_ROOT/config/puma.rb -e production"
+PID_PATH="$APP_ROOT/tmp/pids"
+WEB_SERVER_PID="$PID_PATH/puma.pid"
+SIDEKIQ_PID="$PID_PATH/sidekiq.pid"
+STOP_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:stop"
+START_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:start"
+NAME="gitlab"
+DESC="Gitlab service"
+
+check_pid(){
+ if [ -f $WEB_SERVER_PID ]; then
+ PID=`cat $WEB_SERVER_PID`
+ SPID=`cat $SIDEKIQ_PID`
+ STATUS=`ps aux | grep $PID | grep -v grep | wc -l`
+ else
+ STATUS=0
+ PID=0
+ fi
+}
+
+start() {
+ cd $APP_ROOT
+ check_pid
+ if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then
+ # Program is running, exit with error code 1.
+ echo "Error! $DESC $NAME is currently running!"
+ exit 1
+ else
+ if [ `whoami` = root ]; then
+ sudo -u git -H bash -l -c "RAILS_ENV=production bundle exec puma $DAEMON_OPTS"
+ sudo -u git -H bash -l -c "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &"
+ echo "$DESC started"
+ fi
+ fi
+}
+
+stop() {
+ cd $APP_ROOT
+ check_pid
+ if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then
+ ## Program is running, stop it.
+ kill -QUIT `cat $WEB_SERVER_PID`
+ sudo -u git -H bash -l -c "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &"
+ rm "$WEB_SERVER_PID" >> /dev/null
+ echo "$DESC stopped"
+ else
+ ## Program is not running, exit with error.
+ echo "Error! $DESC not started!"
+ exit 1
+ fi
+}
+
+restart() {
+ cd $APP_ROOT
+ check_pid
+ if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then
+ echo "Restarting $DESC..."
+ kill -USR2 `cat $WEB_SERVER_PID`
+ sudo -u git -H bash -l -c "mkdir -p $PID_PATH && $STOP_SIDEKIQ > /dev/null 2>&1 &"
+ if [ `whoami` = root ]; then
+ sudo -u git -H bash -l -c "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &"
+ fi
+ echo "$DESC restarted."
+ else
+ echo "Error, $NAME not running!"
+ exit 1
+ fi
+}
+
+status() {
+ cd $APP_ROOT
+ check_pid
+ if [ "$PID" -ne 0 -a "$STATUS" -ne 0 ]; then
+ echo "$DESC / Unicorn with PID $PID is running."
+ echo "$DESC / Sidekiq with PID $SPID is running."
+ else
+ echo "$DESC is not running."
+ exit 1
+ fi
+}
+
+## Check to see if we are running as root first.
+## Found at http://www.cyberciti.biz/tips/shell-root-user-check-script.html
+if [ "$(id -u)" != "0" ]; then
+ echo "This script must be run as root"
+ exit 1
+fi
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ restart
+ ;;
+ reload|force-reload)
+ echo -n "Reloading $NAME configuration: "
+ kill -HUP `cat $PID`
+ echo "done."
+ ;;
+ status)
+ status
+ ;;
+ *)
+ echo "Usage: sudo service gitlab {start|stop|restart|reload}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
new file mode 100644
index 00000000000..7428393e664
--- /dev/null
+++ b/lib/support/nginx/gitlab
@@ -0,0 +1,38 @@
+# GITLAB
+# Maintainer: @randx
+# App Version: 5.0
+
+upstream gitlab {
+ server unix:/home/git/gitlab/tmp/sockets/gitlab.socket;
+}
+
+server {
+ listen YOUR_SERVER_IP:80 default_server; # e.g., listen 192.168.1.1:80;
+ server_name YOUR_SERVER_FQDN; # e.g., server_name source.example.com;
+ root /home/git/gitlab/public;
+
+ # individual nginx logs for this gitlab vhost
+ access_log /var/log/nginx/gitlab_access.log;
+ error_log /var/log/nginx/gitlab_error.log;
+
+ location / {
+ # serve static files from defined root folder;.
+ # @gitlab is a named location for the upstream fallback, see below
+ try_files $uri $uri/index.html $uri.html @gitlab;
+ }
+
+ # if a file, which is not found in the root folder is requested,
+ # then the proxy pass the request to the upsteam (gitlab unicorn)
+ location @gitlab {
+ proxy_read_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694
+ proxy_connect_timeout 300; # https://github.com/gitlabhq/gitlabhq/issues/694
+ proxy_redirect off;
+
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Host $http_host;
+ proxy_set_header X-Real-IP $remote_addr;
+
+ proxy_pass http://gitlab;
+ }
+}
+
diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake
index ad6ba43049c..9f28de593e9 100644
--- a/lib/tasks/gitlab/backup.rake
+++ b/lib/tasks/gitlab/backup.rake
@@ -11,8 +11,6 @@ namespace :gitlab do
Rake::Task["gitlab:backup:repo:create"].invoke
Rake::Task["gitlab:backup:uploads:create"].invoke
- Dir.chdir(Gitlab.config.backup.path)
-
# saving additional informations
s = {}
s[:db_version] = "#{ActiveRecord::Migrator.current_version}"
@@ -20,6 +18,8 @@ namespace :gitlab do
s[:gitlab_version] = %x{git rev-parse HEAD}.gsub(/\n/,"")
s[:tar_version] = %x{tar --version | head -1}.gsub(/\n/,"")
+ Dir.chdir(Gitlab.config.backup.path)
+
File.open("#{Gitlab.config.backup.path}/backup_information.yml", "w+") do |file|
file << s.to_yaml.gsub(/^---\n/,'')
end
@@ -101,6 +101,7 @@ namespace :gitlab do
Rake::Task["gitlab:backup:db:restore"].invoke
Rake::Task["gitlab:backup:repo:restore"].invoke
Rake::Task["gitlab:backup:uploads:restore"].invoke
+ Rake::Task["gitlab:shell:setup"].invoke
# cleanup: remove tmp files
print "Deleting tmp directories ... "
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index c8d8d531836..773e496ee41 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -23,6 +23,7 @@ namespace :gitlab do
check_init_script_exists
check_init_script_up_to_date
check_satellites_exist
+ check_redis_version
finished_checking "GitLab"
end
@@ -245,6 +246,23 @@ namespace :gitlab do
fix_and_rerun
end
end
+
+ def check_redis_version
+ print "Redis version >= 2.0.0? ... "
+
+ if run_and_match("redis-cli --version", /redis-cli 2.\d.\d/)
+ puts "yes".green
+ else
+ puts "no".red
+ try_fixing_it(
+ "Update your redis server to a version >= 2.0.0"
+ )
+ for_more_information(
+ "gitlab-public-wiki/wiki/Trouble-Shooting-Guide in section sidekiq"
+ )
+ fix_and_rerun
+ end
+ end
end
@@ -636,11 +654,13 @@ namespace :gitlab do
end
def check_gitlab_shell
+ required_version = '1.4.0'
+
print "GitLab Shell version? ... "
- if gitlab_shell_version.strip == '1.2.0'
- puts 'OK (1.2.0)'.green
+ if gitlab_shell_version.strip == required_version
+ puts "OK (#{required_version})".green
else
- puts 'FAIL. Please update gitlab-shell to v1.2.0'.red
+ puts "FAIL. Please update gitlab-shell to v#{required_version}".red
end
end
end
diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake
index cfab3670fb2..34a4a322c11 100644
--- a/lib/tasks/gitlab/task_helpers.rake
+++ b/lib/tasks/gitlab/task_helpers.rake
@@ -16,7 +16,7 @@ namespace :gitlab do
# Check which OS is running
#
# It will primarily use lsb_relase to determine the OS.
- # It has fallbacks to Debian, SuSE and OS X.
+ # It has fallbacks to Debian, SuSE, OS X and systems running systemd.
def os_name
os_name = run("lsb_release -irs")
os_name ||= if File.readable?('/etc/system-release')
@@ -32,6 +32,9 @@ namespace :gitlab do
os_name ||= if os_x_version = run("sw_vers -productVersion")
"Mac OS X #{os_x_version}"
end
+ os_name ||= if File.readable?('/etc/os-release')
+ File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1]
+ end
os_name.try(:squish!)
end
diff --git a/lib/tasks/migrate/migrate_milestones.rake b/lib/tasks/migrate/migrate_milestones.rake
new file mode 100644
index 00000000000..14c70a3d1c7
--- /dev/null
+++ b/lib/tasks/migrate/migrate_milestones.rake
@@ -0,0 +1,4 @@
+desc "GITLAB | Migrate Milestones"
+task migrate_milestones: :environment do
+ Milestone.where(state: nil).update_all(state: 'active')
+end
diff --git a/lib/tasks/migrate/migrate_mr.rake b/lib/tasks/migrate/migrate_mr.rake
index 6c2312b053c..74b1db03442 100644
--- a/lib/tasks/migrate/migrate_mr.rake
+++ b/lib/tasks/migrate/migrate_mr.rake
@@ -1,6 +1,13 @@
# This taks will reload commits/diff for all merge requests
desc "GITLAB | Migrate Merge Requests"
task migrate_merge_requests: :environment do
+ puts "Since 5.1 old merge request serialization logic was replaced with a better one."
+ puts "It makes old merge request diff invalid for GitLab 5.1+"
+ puts "* * *"
+ puts "This will rebuild commits/diffs info for existing merge requests."
+ puts "You will lose merge request diff if its already merged."
+ ask_to_continue
+
MergeRequest.find_each(batch_size: 20) do |mr|
mr.st_commits = []
mr.save
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 22d1ee91480..a6cf5299791 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -30,11 +30,11 @@ describe "Admin::Users" do
end
it "should create new user" do
- expect { click_button "Save" }.to change {User.count}.by(1)
+ expect { click_button "Create user" }.to change {User.count}.by(1)
end
it "should create user with valid data" do
- click_button "Save"
+ click_button "Create user"
user = User.last
user.name.should == "Big Bang"
user.email.should == "bigbang@mail.com"
@@ -44,14 +44,14 @@ describe "Admin::Users" do
Notify.should_receive(:new_user_email)
User.observers.enable :user_observer do
- click_button "Save"
+ click_button "Create user"
end
end
it "should send valid email to user with email & password" do
Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
User.observers.enable :user_observer do
- click_button "Save"
+ click_button "Create user"
user = User.last
email = ActionMailer::Base.deliveries.last
email.subject.should have_content("Account was created")
@@ -63,7 +63,7 @@ describe "Admin::Users" do
it "should send valid email to user with email without password when signup is enabled" do
Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
User.observers.enable :user_observer do
- click_button "Save"
+ click_button "Create user"
user = User.last
email = ActionMailer::Base.deliveries.last
email.subject.should have_content("Account was created")
@@ -102,7 +102,7 @@ describe "Admin::Users" do
fill_in "user_name", with: "Big Bang"
fill_in "user_email", with: "bigbang@mail.com"
check "user_admin"
- click_button "Save"
+ click_button "Save changes"
end
it "should show page with new data" do
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
deleted file mode 100644
index bf2cd98eba1..00000000000
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require "spec_helper"
-
-describe Gitlab::Git::Commit do
- let(:commit) { create(:project_with_code).repository.commit }
-
- describe "Commit info" do
- before do
- @committer = double(
- email: 'mike@smith.com',
- name: 'Mike Smith'
- )
-
- @author = double(
- email: 'john@smith.com',
- name: 'John Smith'
- )
-
- @raw_commit = double(
- id: "bcf03b5de6abcf03b5de6c",
- author: @author,
- committer: @committer,
- committed_date: Date.yesterday,
- authored_date: Date.yesterday,
- parents: [],
- message: 'Refactoring specs'
- )
-
- @commit = Gitlab::Git::Commit.new(@raw_commit)
- end
-
- it { @commit.short_id.should == "bcf03b5de6a" }
- it { @commit.safe_message.should == @raw_commit.message }
- it { @commit.created_at.should == @raw_commit.committed_date }
- it { @commit.author_email.should == @author.email }
- it { @commit.author_name.should == @author.name }
- it { @commit.committer_name.should == @committer.name }
- it { @commit.committer_email.should == @committer.email }
- it { @commit.different_committer?.should be_true }
- end
-end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
deleted file mode 100644
index 2b0550aa72a..00000000000
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-require "spec_helper"
-
-describe Gitlab::Git::Repository do
- let(:repository) { Gitlab::Git::Repository.new('gitlabhq', 'master') }
-
- describe "Respond to" do
- subject { repository }
-
- it { should respond_to(:repo) }
- it { should respond_to(:tree) }
- it { should respond_to(:root_ref) }
- it { should respond_to(:tags) }
- it { should respond_to(:commit) }
- it { should respond_to(:commits) }
- it { should respond_to(:commits_between) }
- it { should respond_to(:commits_with_refs) }
- end
-
-
- describe "#discover_default_branch" do
- let(:master) { 'master' }
- let(:stable) { 'stable' }
-
- it "returns 'master' when master exists" do
- repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])
- repository.discover_default_branch.should == 'master'
- end
-
- it "returns non-master when master exists but default branch is set to something else" do
- repository.root_ref = 'stable'
- repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])
- repository.discover_default_branch.should == 'stable'
- end
-
- it "returns a non-master branch when only one exists" do
- repository.should_receive(:branch_names).at_least(:once).and_return([stable])
- repository.discover_default_branch.should == 'stable'
- end
-
- it "returns nil when no branch exists" do
- repository.should_receive(:branch_names).at_least(:once).and_return([])
- repository.discover_default_branch.should be_nil
- end
- end
-
- describe :commit do
- it "should return first head commit if without params" do
- repository.commit.id.should == repository.repo.commits.first.id
- end
-
- it "should return valid commit" do
- repository.commit(ValidCommit::ID).should be_valid_commit
- end
-
- it "should return nil" do
- repository.commit("+123_4532530XYZ").should be_nil
- end
- end
-
- describe :tree do
- before do
- @commit = repository.commit(ValidCommit::ID)
- end
-
- it "should raise error w/o arguments" do
- lambda { repository.tree }.should raise_error
- end
-
- it "should return root tree for commit" do
- tree = repository.tree(@commit)
- tree.contents.size.should == ValidCommit::FILES_COUNT
- tree.contents.map(&:name).should == ValidCommit::FILES
- end
-
- it "should return root tree for commit with correct path" do
- tree = repository.tree(@commit, ValidCommit::C_FILE_PATH)
- tree.contents.map(&:name).should == ValidCommit::C_FILES
- end
-
- it "should return root tree for commit with incorrect path" do
- repository.tree(@commit, "invalid_path").should be_nil
- end
- end
-
- describe "commits" do
- subject do
- commits = repository.commits('master', 'app', 3, 1)
- commits.map { |c| c.id }
- end
-
- it { should have(3).elements }
- it { should include("8716fc78f3c65bbf7bcf7b574febd583bc5d2812") }
- it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
- end
-
- describe "commits_between" do
- subject do
- commits = repository.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
- "8470d70da67355c9c009e4401746b1d5410af2e3")
- commits.map { |c| c.id }
- end
-
- it { should have(3).elements }
- it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
- it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
- end
-
- describe "branch names" do
- subject { repository.branch_names }
-
- it { should have(32).elements }
- it { should include("master") }
- it { should_not include("branch-from-space") }
- end
-
- describe "tag names" do
- subject { repository.tag_names }
-
- it { should have(16).elements }
- it { should include("v1.2.0") }
- it { should_not include("v5.0.0") }
- end
-end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 4e276deaabe..380bbe7351f 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -120,7 +120,7 @@ describe User do
end
it { @user.several_namespaces?.should be_true }
- it { @user.namespaces.should == [@user.namespace, @group] }
+ it { @user.namespaces.should include(@user.namespace, @group) }
it { @user.authorized_groups.should == [@group] }
it { @user.owned_groups.should == [@group] }
end
@@ -155,8 +155,8 @@ describe User do
it { User.filter("admins").should == [@admin] }
it { User.filter("blocked").should == [@blocked] }
- it { User.filter("wop").should == [@user, @admin, @blocked] }
- it { User.filter(nil).should == [@user, @admin] }
+ it { User.filter("wop").should include(@user, @admin, @blocked) }
+ it { User.filter(nil).should include(@user, @admin) }
end
describe :not_in_project do
@@ -166,7 +166,7 @@ describe User do
@project = create :project
end
- it { User.not_in_project(@project).should == [@user, @project.owner] }
+ it { User.not_in_project(@project).should include(@user, @project.owner) }
end
describe 'normal user' do
diff --git a/spec/observers/merge_request_observer_spec.rb b/spec/observers/merge_request_observer_spec.rb
index 24a05646cb5..82c3fbc8a30 100644
--- a/spec/observers/merge_request_observer_spec.rb
+++ b/spec/observers/merge_request_observer_spec.rb
@@ -12,6 +12,8 @@ describe MergeRequestObserver do
before { subject.stub(:current_user).and_return(some_user) }
before { subject.stub(notification: mock('NotificationService').as_null_object) }
+ before(:each) { enable_observers }
+
subject { MergeRequestObserver.instance }
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 362c116b64b..1a93148139e 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -249,7 +249,7 @@ describe Gitlab::API do
response.status.should == 200
json_response.should be_an Array
json_response.count.should == 2
- json_response.first['email'].should == user.email
+ json_response.map { |u| u['email'] }.should include user.email
end
it "finds team members with query string" do
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 175698ac9c9..efc629e6478 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -1,3 +1,5 @@
+require 'rspec/mocks'
+
module TestEnv
extend self
@@ -13,6 +15,8 @@ module TestEnv
# - remove_key
#
def init(opts = {})
+ RSpec::Mocks::setup(self)
+
# Disable observers to improve test speed
#
# You can enable it in whole test case where needed by next string:
@@ -28,6 +32,7 @@ module TestEnv
# Use tmp dir for FS manipulations
repos_path = Rails.root.join('tmp', 'test-git-base-path')
Gitlab.config.gitlab_shell.stub(repos_path: repos_path)
+ Gitlab::Git::Repository.stub(repos_path: repos_path)
GollumWiki.any_instance.stub(:init_repo) do |path|
create_temp_repo(File.join(repos_path, "#{path}.git"))
@@ -82,6 +87,6 @@ module TestEnv
end
def disable_mailer
- ActionMailer::Base.perform_deliveries = false
+ NotificationService.any_instance.stub(mailer: double.as_null_object)
end
end