summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Frenkel <ifrenkel@gitlab.com>2019-10-28 11:30:55 -0400
committerIgor Frenkel <ifrenkel@gitlab.com>2019-10-28 11:30:55 -0400
commit77e53d398e23b3ffe20aacc85d6e288ffad06de7 (patch)
tree8299420f6a2d7667df821eecc9367435d16c57a1
parent8dfcafc64e7cc4a4729b47f32e72dc57f8b0698f (diff)
parenta77db6bc47d8cdd9edae2ec22f640821d0794404 (diff)
downloadgitlab-ce-34577-add-dep-scanner-var-maven.tar.gz
Merge branch 'master' into 34577-add-dep-scanner-var-maven34577-add-dep-scanner-var-maven
-rw-r--r--Gemfile6
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/javascripts/boards/components/issue_card_inner.vue4
-rw-r--r--app/assets/javascripts/boards/index.js4
-rw-r--r--app/assets/javascripts/boards/stores/getters.js3
-rw-r--r--app/assets/javascripts/boards/stores/index.js6
-rw-r--r--app/assets/javascripts/boards/stores/state.js2
-rw-r--r--app/assets/javascripts/boards/toggle_labels.js1
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue41
-rw-r--r--app/assets/javascripts/error_tracking/store/getters.js4
-rw-r--r--app/assets/javascripts/error_tracking/store/index.js2
-rw-r--r--app/assets/stylesheets/pages/boards.scss12
-rw-r--r--app/controllers/concerns/routable_actions.rb2
-rw-r--r--app/controllers/projects/pipelines_controller.rb21
-rw-r--r--app/finders/todos_finder.rb8
-rw-r--r--app/models/clusters/cluster.rb4
-rw-r--r--app/services/clusters/applications/base_service.rb8
-rw-r--r--app/services/projects/container_repository/delete_tags_service.rb20
-rw-r--r--app/views/ci/variables/_url_query_variable_row.html.haml28
-rw-r--r--app/views/errors/not_found.html.haml2
-rw-r--r--app/views/profiles/show.html.haml3
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--app/views/projects/pipelines/new.html.haml7
-rw-r--r--app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml4
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml1
-rw-r--r--changelogs/unreleased/13401-close-gitlab-issue-on-recovery-alerts-from-prometheus.yml5
-rw-r--r--changelogs/unreleased/24146-query-string-params.yml5
-rw-r--r--changelogs/unreleased/30161-expose-merge-request-status-in-api.yml5
-rw-r--r--changelogs/unreleased/32198-banner-alerting-of-project-move-is-showing-up-everywhere.yml5
-rw-r--r--changelogs/unreleased/backstage-remove-export-designs-feature-flag.yml5
-rw-r--r--changelogs/unreleased/drop-id-of-ci-trace-sectinos.yml5
-rw-r--r--changelogs/unreleased/dz-ask-users-to-enable-registry.yml5
-rw-r--r--changelogs/unreleased/jc-dont-render-commit-links.yml5
-rw-r--r--changelogs/unreleased/lm-search-list-of-sentry-errors.yml5
-rw-r--r--changelogs/unreleased/patch-35.yml5
-rw-r--r--changelogs/unreleased/record-sidekiq-queuing-latency.yml5
-rw-r--r--changelogs/unreleased/sh-gitaly-duration-measurement.yml5
-rw-r--r--changelogs/unreleased/sh-set-httponly-experimentation-subject-id.yml5
-rw-r--r--config/initializers/rack_attack_git_basic_auth.rb20
-rw-r--r--config/initializers/rack_attack_logging.rb6
-rw-r--r--config/puma.example.development.rb10
-rw-r--r--db/migrate/20191003015155_add_self_managed_prometheus_alerts.rb1
-rw-r--r--db/post_migrate/20191017180026_drop_ci_build_trace_sections_id.rb19
-rw-r--r--db/schema.rb4
-rw-r--r--doc/administration/geo/replication/object_storage.md2
-rw-r--r--doc/administration/git_annex.md242
-rw-r--r--doc/administration/gitaly/index.md2
-rw-r--r--doc/administration/index.md7
-rw-r--r--doc/administration/lfs/img/git-annex-branches.png (renamed from doc/workflow/lfs/images/git-annex-branches.png)bin32164 -> 32164 bytes
-rw-r--r--doc/administration/lfs/img/lfs-icon.png (renamed from doc/workflow/lfs/img/lfs-icon.png)bin4317 -> 4317 bytes
-rw-r--r--doc/administration/lfs/lfs_administration.md273
-rw-r--r--doc/administration/lfs/manage_large_binaries_with_git_lfs.md266
-rw-r--r--doc/administration/lfs/migrate_from_git_annex_to_git_lfs.md254
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md2
-rw-r--r--doc/administration/repository_storage_types.md5
-rw-r--r--doc/administration/timezone.md37
-rw-r--r--doc/api/merge_requests.md12
-rw-r--r--doc/ci/ci_cd_for_external_repos/bitbucket_integration.md2
-rw-r--r--doc/ci/ci_cd_for_external_repos/github_integration.md2
-rw-r--r--doc/ci/ci_cd_for_external_repos/index.md2
-rw-r--r--doc/ci/docker/using_docker_build.md22
-rw-r--r--doc/ci/environments.md2
-rw-r--r--doc/ci/examples/laravel_with_gitlab_and_envoy/index.md2
-rw-r--r--doc/ci/pipelines.md2
-rw-r--r--doc/ci/quick_start/README.md2
-rw-r--r--doc/ci/variables/README.md26
-rw-r--r--doc/ci/variables/deprecated_variables.md12
-rw-r--r--doc/ci/yaml/README.md2
-rw-r--r--doc/development/contributing/merge_request_workflow.md2
-rw-r--r--doc/development/git_object_deduplication.md2
-rw-r--r--doc/development/pipelines.md2
-rw-r--r--doc/development/repository_mirroring.md2
-rw-r--r--doc/gitlab-basics/README.md3
-rw-r--r--doc/gitlab-basics/feature_branch_workflow.md35
-rw-r--r--doc/gitlab-basics/fork-project.md2
-rw-r--r--doc/install/aws/index.md2
-rw-r--r--doc/intro/README.md2
-rw-r--r--doc/raketasks/backup_restore.md2
-rw-r--r--doc/topics/autodevops/quick_start_guide.md2
-rw-r--r--doc/topics/git/index.md2
-rw-r--r--doc/topics/git/migrate_to_git_lfs/index.md6
-rw-r--r--doc/topics/gitlab_flow.md330
-rw-r--r--doc/topics/img/gitlab_flow.png (renamed from doc/workflow/img/gitlab_flow.png)bin47430 -> 47430 bytes
-rw-r--r--doc/topics/img/gitlab_flow_ci_mr.png (renamed from doc/workflow/img/ci_mr.png)bin12024 -> 12024 bytes
-rw-r--r--doc/topics/img/gitlab_flow_close_issue_mr.png (renamed from doc/workflow/img/close_issue_mr.png)bin42108 -> 42108 bytes
-rw-r--r--doc/topics/img/gitlab_flow_environment_branches.png (renamed from doc/workflow/img/environment_branches.png)bin12354 -> 12354 bytes
-rw-r--r--doc/topics/img/gitlab_flow_four_stages.png (renamed from doc/workflow/img/four_stages.png)bin7124 -> 7124 bytes
-rw-r--r--doc/topics/img/gitlab_flow_git_pull.png (renamed from doc/workflow/img/git_pull.png)bin28701 -> 28701 bytes
-rw-r--r--doc/topics/img/gitlab_flow_gitdashflow.png (renamed from doc/workflow/img/gitdashflow.png)bin68177 -> 68177 bytes
-rw-r--r--doc/topics/img/gitlab_flow_github_flow.png (renamed from doc/workflow/img/github_flow.png)bin6173 -> 6173 bytes
-rw-r--r--doc/topics/img/gitlab_flow_good_commit.png (renamed from doc/workflow/img/good_commit.png)bin8740 -> 8740 bytes
-rw-r--r--doc/topics/img/gitlab_flow_merge_commits.png (renamed from doc/workflow/img/merge_commits.png)bin7564 -> 7564 bytes
-rw-r--r--doc/topics/img/gitlab_flow_merge_request.png (renamed from doc/workflow/img/merge_request.png)bin47225 -> 47225 bytes
-rw-r--r--doc/topics/img/gitlab_flow_messy_flow.png (renamed from doc/workflow/img/messy_flow.png)bin11663 -> 11663 bytes
-rw-r--r--doc/topics/img/gitlab_flow_mr_inline_comments.png (renamed from doc/workflow/img/mr_inline_comments.png)bin52503 -> 52503 bytes
-rw-r--r--doc/topics/img/gitlab_flow_production_branch.png (renamed from doc/workflow/img/production_branch.png)bin7262 -> 7262 bytes
-rw-r--r--doc/topics/img/gitlab_flow_rebase.png (renamed from doc/workflow/img/rebase.png)bin28939 -> 28939 bytes
-rw-r--r--doc/topics/img/gitlab_flow_release_branches.png (renamed from doc/workflow/img/release_branches.png)bin12736 -> 12736 bytes
-rw-r--r--doc/topics/img/gitlab_flow_remove_checkbox.png (renamed from doc/workflow/img/remove_checkbox.png)bin6904 -> 6904 bytes
-rw-r--r--doc/topics/index.md1
-rw-r--r--doc/university/README.md2
-rw-r--r--doc/university/training/gitlab_flow.md2
-rw-r--r--doc/user/admin_area/settings/account_and_limit_settings.md2
-rw-r--r--doc/user/admin_area/settings/usage_statistics.md4
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md2
-rw-r--r--doc/user/analytics/cycle_analytics.md2
-rw-r--r--doc/user/group/epics/index.md2
-rw-r--r--doc/user/img/todos_add_todo_sidebar.png (renamed from doc/workflow/img/todos_add_todo_sidebar.png)bin17524 -> 17524 bytes
-rw-r--r--doc/user/img/todos_icon.png (renamed from doc/workflow/img/todos_icon.png)bin4910 -> 4910 bytes
-rw-r--r--doc/user/img/todos_index.png (renamed from doc/workflow/img/todos_index.png)bin98239 -> 98239 bytes
-rw-r--r--doc/user/img/todos_mark_done_sidebar.png (renamed from doc/workflow/img/todos_mark_done_sidebar.png)bin17619 -> 17619 bytes
-rw-r--r--doc/user/img/todos_todo_list_item.png (renamed from doc/workflow/img/todo_list_item.png)bin18776 -> 18776 bytes
-rw-r--r--doc/user/index.md9
-rw-r--r--doc/user/profile/img/notification_global_settings.png (renamed from doc/workflow/img/notification_global_settings.png)bin67652 -> 67652 bytes
-rw-r--r--doc/user/profile/img/notification_group_settings.png (renamed from doc/workflow/img/notification_group_settings.png)bin54362 -> 54362 bytes
-rw-r--r--doc/user/profile/img/notification_project_settings.png (renamed from doc/workflow/img/notification_project_settings.png)bin58864 -> 58864 bytes
-rw-r--r--doc/user/profile/index.md2
-rw-r--r--doc/user/profile/notifications.md176
-rw-r--r--doc/user/profile/preferences.md2
-rw-r--r--doc/user/project/clusters/index.md10
-rw-r--r--doc/user/project/img/time_tracking_example_v12_2.png (renamed from doc/workflow/time_tracking/img/time_tracking_example_v12_2.png)bin16362 -> 16362 bytes
-rw-r--r--doc/user/project/img/time_tracking_sidebar_v8_16.png (renamed from doc/workflow/time_tracking/img/time_tracking_sidebar_v8_16.png)bin9068 -> 9068 bytes
-rw-r--r--doc/user/project/import/github.md2
-rw-r--r--doc/user/project/index.md3
-rw-r--r--doc/user/project/integrations/prometheus.md2
-rw-r--r--doc/user/project/issues/csv_export.md4
-rw-r--r--doc/user/project/issues/design_management.md2
-rw-r--r--doc/user/project/issues/due_dates.md2
-rw-r--r--doc/user/project/issues/img/issue_weight.png (renamed from doc/workflow/issue_weight/issue.png)bin69564 -> 69564 bytes
-rw-r--r--doc/user/project/issues/issue_data_and_actions.md14
-rw-r--r--doc/user/project/issues/issue_weight.md25
-rw-r--r--doc/user/project/labels.md4
-rw-r--r--doc/user/project/merge_requests/index.md2
-rw-r--r--doc/user/project/milestones/index.md2
-rw-r--r--doc/user/project/operations/error_tracking.md1
-rw-r--r--doc/user/project/operations/img/error_tracking_list.pngbin60762 -> 760603 bytes
-rw-r--r--doc/user/project/protected_branches.md2
-rw-r--r--doc/user/project/releases/img/new_tag.png (renamed from doc/workflow/releases/new_tag.png)bin42439 -> 42439 bytes
-rw-r--r--doc/user/project/releases/img/tags.png (renamed from doc/workflow/releases/tags.png)bin44666 -> 44666 bytes
-rw-r--r--doc/user/project/releases/index.md20
-rw-r--r--doc/user/project/repository/file_finder.md45
-rw-r--r--doc/user/project/repository/forking_workflow.md55
-rw-r--r--doc/user/project/repository/img/file_finder_find_button.png (renamed from doc/workflow/img/file_finder_find_button.png)bin14565 -> 14565 bytes
-rw-r--r--doc/user/project/repository/img/file_finder_find_file.png (renamed from doc/workflow/img/file_finder_find_file.png)bin19478 -> 19478 bytes
-rw-r--r--doc/user/project/repository/img/forking_workflow_branch_select.png (renamed from doc/workflow/forking/branch_select.png)bin18042 -> 18042 bytes
-rw-r--r--doc/user/project/repository/img/forking_workflow_choose_namespace.png (renamed from doc/workflow/img/forking_workflow_choose_namespace.png)bin35084 -> 35084 bytes
-rw-r--r--doc/user/project/repository/img/forking_workflow_fork_button.png (renamed from doc/workflow/img/forking_workflow_fork_button.png)bin25754 -> 25754 bytes
-rw-r--r--doc/user/project/repository/img/forking_workflow_merge_request.png (renamed from doc/workflow/forking/merge_request.png)bin24625 -> 24625 bytes
-rw-r--r--doc/user/project/repository/img/forking_workflow_path_taken_error.png (renamed from doc/workflow/img/forking_workflow_path_taken_error.png)bin21497 -> 21497 bytes
-rw-r--r--doc/user/project/repository/img/repository_mirroring_copy_ssh_public_key_button.png (renamed from doc/workflow/img/copy_ssh_public_key_button.png)bin11225 -> 11225 bytes
-rw-r--r--doc/user/project/repository/img/repository_mirroring_force_update.png (renamed from doc/workflow/img/repository_mirroring_force_update.png)bin13586 -> 13586 bytes
-rw-r--r--doc/user/project/repository/img/repository_mirroring_pull_settings_lower.png (renamed from doc/workflow/img/repository_mirroring_pull_settings_lower.png)bin58056 -> 58056 bytes
-rw-r--r--doc/user/project/repository/img/repository_mirroring_pull_settings_upper.png (renamed from doc/workflow/img/repository_mirroring_pull_settings_upper.png)bin50084 -> 50084 bytes
-rw-r--r--doc/user/project/repository/img/repository_mirroring_push_settings.png (renamed from doc/workflow/img/repository_mirroring_push_settings.png)bin72515 -> 72515 bytes
-rw-r--r--doc/user/project/repository/index.md5
-rw-r--r--doc/user/project/repository/repository_mirroring.md430
-rw-r--r--doc/user/project/time_tracking.md92
-rw-r--r--doc/user/search/index.md4
-rw-r--r--doc/user/shortcuts.md135
-rw-r--r--doc/user/todos.md142
-rw-r--r--doc/workflow/README.md18
-rw-r--r--doc/workflow/file_finder.md44
-rw-r--r--doc/workflow/forking_workflow.md54
-rw-r--r--doc/workflow/git_annex.md239
-rw-r--r--doc/workflow/git_lfs.md4
-rw-r--r--doc/workflow/gitlab_flow.md329
-rw-r--r--doc/workflow/issue_weight.md24
-rw-r--r--doc/workflow/lfs/lfs_administration.md272
-rw-r--r--doc/workflow/lfs/manage_large_binaries_with_git_lfs.md265
-rw-r--r--doc/workflow/lfs/migrate_from_git_annex_to_git_lfs.md255
-rw-r--r--doc/workflow/notifications.md175
-rw-r--r--doc/workflow/releases.md25
-rw-r--r--doc/workflow/repository_mirroring.md427
-rw-r--r--doc/workflow/shortcuts.md133
-rw-r--r--doc/workflow/time_tracking.md90
-rw-r--r--doc/workflow/timezone.md40
-rw-r--r--doc/workflow/todos.md141
-rw-r--r--doc/workflow/workflow.md34
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/gitlab/experimentation.rb3
-rw-r--r--lib/gitlab/gitaly_client.rb27
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb26
-rw-r--r--lib/gitlab/import_export/project_tree_restorer.rb8
-rw-r--r--lib/gitlab/instrumentation_helper.rb44
-rw-r--r--lib/gitlab/sidekiq_logging/structured_logger.rb11
-rw-r--r--lib/gitlab/sidekiq_middleware/metrics.rb16
-rw-r--r--locale/gitlab.pot12
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb5
-rw-r--r--spec/controllers/groups/milestones_controller_spec.rb18
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb18
-rw-r--r--spec/features/populate_new_pipeline_vars_with_params_spec.rb32
-rw-r--r--spec/features/profiles/user_edit_profile_spec.rb28
-rw-r--r--spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb13
-rw-r--r--spec/finders/todos_finder_spec.rb23
-rw-r--r--spec/frontend/boards/stores/getters_spec.js21
-rw-r--r--spec/frontend/error_tracking/store/getters_spec.js33
-rw-r--r--spec/frontend/releases/list/components/release_block_spec.js12
-rw-r--r--spec/javascripts/boards/board_card_spec.js2
-rw-r--r--spec/javascripts/boards/board_list_common_spec.js2
-rw-r--r--spec/javascripts/boards/issue_card_spec.js2
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb2
-rw-r--r--spec/lib/gitlab/instrumentation_helper_spec.rb37
-rw-r--r--spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb2
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb83
-rw-r--r--spec/requests/api/merge_requests_spec.rb2
-rw-r--r--spec/requests/git_http_spec.rb26
-rw-r--r--spec/services/projects/container_repository/delete_tags_service_spec.rb16
-rw-r--r--spec/views/profiles/show.html.haml_spec.rb1
-rw-r--r--vendor/aws/cloudformation/eks_cluster.yaml340
209 files changed, 3769 insertions, 2776 deletions
diff --git a/Gemfile b/Gemfile
index c0e31fb6c5c..493bd42ce3a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -259,9 +259,6 @@ gem 'loofah', '~> 2.2'
# Working with license
gem 'licensee', '~> 8.9'
-# Protect against bruteforcing
-gem 'rack-attack', '~> 4.4.1'
-
# Ace editor
gem 'ace-rails-ap', '~> 4.1.0'
@@ -293,6 +290,9 @@ gem 'base32', '~> 0.3.0'
gem "gitlab-license", "~> 1.0"
+# Protect against bruteforcing
+gem 'rack-attack', '~> 6.2.0'
+
# Sentry integration
gem 'sentry-raven', '~> 2.9'
diff --git a/Gemfile.lock b/Gemfile.lock
index 134ee9a2c10..d3e98209694 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -734,8 +734,8 @@ GEM
rack (2.0.7)
rack-accept (0.4.5)
rack (>= 0.4)
- rack-attack (4.4.1)
- rack
+ rack-attack (6.2.0)
+ rack (>= 1.0, < 3)
rack-cors (1.0.2)
rack-oauth2 (1.9.3)
activesupport
@@ -1256,7 +1256,7 @@ DEPENDENCIES
puma (~> 3.12)
puma_worker_killer
rack (~> 2.0.7)
- rack-attack (~> 4.4.1)
+ rack-attack (~> 6.2.0)
rack-cors (~> 1.0.0)
rack-oauth2 (~> 1.9.3)
rack-proxy (~> 0.6.0)
diff --git a/app/assets/javascripts/boards/components/issue_card_inner.vue b/app/assets/javascripts/boards/components/issue_card_inner.vue
index 40d75d53f75..d37e49bab46 100644
--- a/app/assets/javascripts/boards/components/issue_card_inner.vue
+++ b/app/assets/javascripts/boards/components/issue_card_inner.vue
@@ -1,5 +1,6 @@
<script>
import _ from 'underscore';
+import { mapState } from 'vuex';
import { GlTooltipDirective } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
@@ -63,6 +64,7 @@ export default {
};
},
computed: {
+ ...mapState(['isShowingLabels']),
numberOverLimit() {
return this.issue.assignees.length - this.limitBeforeCounter;
},
@@ -92,7 +94,7 @@ export default {
return false;
},
showLabelFooter() {
- return this.issue.labels.find(l => this.showLabel(l)) !== undefined;
+ return this.isShowingLabels && this.issue.labels.find(this.showLabel);
},
issueReferencePath() {
const { referencePath, groupId } = this.issue;
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index befca70eeae..e76e2341dfd 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -13,6 +13,7 @@ import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list';
import '~/boards/models/milestone';
import '~/boards/models/project';
+import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
import ModalStore from '~/boards/stores/modal_store';
import BoardService from 'ee_else_ce/boards/services/board_service';
@@ -29,6 +30,7 @@ import {
} from '~/lib/utils/common_utils';
import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
import toggleFocusMode from 'ee_else_ce/boards/toggle_focus';
+import toggleLabels from 'ee_else_ce/boards/toggle_labels';
import {
setPromotionState,
setWeigthFetchingState,
@@ -67,6 +69,7 @@ export default () => {
BoardSidebar,
BoardAddIssuesModal,
},
+ store,
data: {
state: boardsStore.state,
loading: true,
@@ -314,5 +317,6 @@ export default () => {
}
toggleFocusMode(ModalStore, boardsStore, $boardApp);
+ toggleLabels();
mountMultipleBoardsSwitcher();
};
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
new file mode 100644
index 00000000000..4de1576099d
--- /dev/null
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -0,0 +1,3 @@
+export default {
+ getLabelToggleState: state => (state.isShowingLabels ? 'on' : 'off'),
+};
diff --git a/app/assets/javascripts/boards/stores/index.js b/app/assets/javascripts/boards/stores/index.js
index f70395a3771..471b952a212 100644
--- a/app/assets/javascripts/boards/stores/index.js
+++ b/app/assets/javascripts/boards/stores/index.js
@@ -1,14 +1,18 @@
import Vue from 'vue';
import Vuex from 'vuex';
import state from 'ee_else_ce/boards/stores/state';
+import getters from 'ee_else_ce/boards/stores/getters';
import actions from 'ee_else_ce/boards/stores/actions';
import mutations from 'ee_else_ce/boards/stores/mutations';
Vue.use(Vuex);
-export default () =>
+export const createStore = () =>
new Vuex.Store({
state,
+ getters,
actions,
mutations,
});
+
+export default createStore();
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index dd16abb01a5..24f44dc5629 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -1,3 +1,3 @@
export default () => ({
- // ...
+ isShowingLabels: true,
});
diff --git a/app/assets/javascripts/boards/toggle_labels.js b/app/assets/javascripts/boards/toggle_labels.js
new file mode 100644
index 00000000000..2d1ec238274
--- /dev/null
+++ b/app/assets/javascripts/boards/toggle_labels.js
@@ -0,0 +1 @@
+export default () => {};
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
index cd298e2c692..a76eb747c34 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -1,6 +1,13 @@
<script>
-import { mapActions, mapState } from 'vuex';
-import { GlEmptyState, GlButton, GlLink, GlLoadingIcon, GlTable } from '@gitlab/ui';
+import { mapActions, mapState, mapGetters } from 'vuex';
+import {
+ GlEmptyState,
+ GlButton,
+ GlLink,
+ GlLoadingIcon,
+ GlTable,
+ GlSearchBoxByType,
+} from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale';
@@ -20,6 +27,7 @@ export default {
GlLink,
GlLoadingIcon,
GlTable,
+ GlSearchBoxByType,
Icon,
TimeAgo,
},
@@ -48,8 +56,17 @@ export default {
required: true,
},
},
+ data() {
+ return {
+ errorSearchQuery: '',
+ };
+ },
computed: {
...mapState(['errors', 'externalUrl', 'loading']),
+ ...mapGetters(['filterErrorsByTitle']),
+ filteredErrors() {
+ return this.errorSearchQuery ? this.filterErrorsByTitle(this.errorSearchQuery) : this.errors;
+ },
},
created() {
if (this.errorTrackingEnabled) {
@@ -71,10 +88,17 @@ export default {
<gl-loading-icon :size="3" />
</div>
<div v-else>
- <div class="d-flex justify-content-end">
+ <div class="d-flex flex-row justify-content-around bg-secondary border">
+ <gl-search-box-by-type
+ v-model="errorSearchQuery"
+ class="col-lg-10 m-3 p-0"
+ :placeholder="__('Search or filter results...')"
+ type="search"
+ autofocus
+ />
<gl-button
v-track-event="trackViewInSentryOptions(externalUrl)"
- class="my-3 ml-auto"
+ class="m-3"
variant="primary"
:href="externalUrl"
target="_blank"
@@ -84,7 +108,14 @@ export default {
</gl-button>
</div>
- <gl-table :items="errors" :fields="$options.fields" :show-empty="true" fixed stacked="sm">
+ <gl-table
+ class="mt-3"
+ :items="filteredErrors"
+ :fields="$options.fields"
+ :show-empty="true"
+ fixed
+ stacked="sm"
+ >
<template slot="HEAD_events" slot-scope="data">
<div class="text-md-right">{{ data.label }}</div>
</template>
diff --git a/app/assets/javascripts/error_tracking/store/getters.js b/app/assets/javascripts/error_tracking/store/getters.js
new file mode 100644
index 00000000000..1a2ec62f79f
--- /dev/null
+++ b/app/assets/javascripts/error_tracking/store/getters.js
@@ -0,0 +1,4 @@
+export const filterErrorsByTitle = state => errorQuery =>
+ state.errors.filter(error => error.title.match(new RegExp(`${errorQuery}`, 'i')));
+
+export default () => {};
diff --git a/app/assets/javascripts/error_tracking/store/index.js b/app/assets/javascripts/error_tracking/store/index.js
index 3136682fb64..3ba05e22727 100644
--- a/app/assets/javascripts/error_tracking/store/index.js
+++ b/app/assets/javascripts/error_tracking/store/index.js
@@ -1,6 +1,7 @@
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
+import * as getters from './getters';
import mutations from './mutations';
Vue.use(Vuex);
@@ -14,6 +15,7 @@ export const createStore = () =>
},
actions,
mutations,
+ getters,
});
export default createStore();
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index 2a7a53d8bd7..45d0579052a 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -545,3 +545,15 @@
.board-issue-path.js-show-tooltip {
cursor: help;
}
+
+.board-labels-toggle-wrapper {
+ /**
+ * Make the wrapper the same height as a button so it aligns properly when the
+ * filtered-search-box input element increases in size on Linux smaller breakpoints
+ */
+ height: 34px;
+
+ @include media-breakpoint-down(sm) {
+ margin-bottom: 10px;
+ }
+}
diff --git a/app/controllers/concerns/routable_actions.rb b/app/controllers/concerns/routable_actions.rb
index 45f9888a040..1b2e6461dee 100644
--- a/app/controllers/concerns/routable_actions.rb
+++ b/app/controllers/concerns/routable_actions.rb
@@ -47,7 +47,7 @@ module RoutableActions
canonical_path = routable.full_path
if canonical_path != requested_full_path
- if canonical_path.casecmp(requested_full_path) != 0
+ if !request.xhr? && request.format.html? && canonical_path.casecmp(requested_full_path) != 0
flash[:notice] = "#{routable.class.to_s.titleize} '#{requested_full_path}' was moved to '#{canonical_path}'. Please update any links and bookmarks that may still have the old path."
end
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 106ef1b72c1..6770ff37d91 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -156,14 +156,21 @@ class Projects::PipelinesController < Projects::ApplicationController
def test_report
return unless Feature.enabled?(:junit_pipeline_view, project)
- if pipeline_test_report == :error
- render json: { status: :error_parsing_report }
- return
- end
+ respond_to do |format|
+ format.html do
+ render 'show'
+ end
- render json: TestReportSerializer
- .new(current_user: @current_user)
- .represent(pipeline_test_report)
+ format.json do
+ if pipeline_test_report == :error
+ render json: { status: :error_parsing_report }
+ else
+ render json: TestReportSerializer
+ .new(current_user: @current_user)
+ .represent(pipeline_test_report)
+ end
+ end
+ end
end
private
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index 2b46e51290f..82acb5e9d45 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -188,11 +188,9 @@ class TodosFinder
end
def by_state(items)
- if params[:state].to_s == 'done'
- items.done
- else
- items.pending
- end
+ return items.pending if params[:state].blank?
+
+ items.with_states(params[:state])
end
def by_type(items)
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index e3e2f06c313..acd744bfaf5 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -9,8 +9,6 @@ module Clusters
self.table_name = 'clusters'
- PROJECT_ONLY_APPLICATIONS = {
- }.freeze
APPLICATIONS = {
Applications::Helm.application_name => Applications::Helm,
Applications::Ingress.application_name => Applications::Ingress,
@@ -20,7 +18,7 @@ module Clusters
Applications::Jupyter.application_name => Applications::Jupyter,
Applications::Knative.application_name => Applications::Knative,
Applications::ElasticStack.application_name => Applications::ElasticStack
- }.merge(PROJECT_ONLY_APPLICATIONS).freeze
+ }.freeze
DEFAULT_ENVIRONMENT = '*'
KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN'
diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb
index b39fc7d20a9..1a6f6e3aa6f 100644
--- a/app/services/clusters/applications/base_service.rb
+++ b/app/services/clusters/applications/base_service.rb
@@ -64,19 +64,13 @@ module Clusters
end
def invalid_application?
- unknown_application? || (!cluster.project_type? && project_only_application?) || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack))
+ unknown_application? || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack))
end
def unknown_application?
Clusters::Cluster::APPLICATIONS.keys.exclude?(application_name)
end
- # These applications will need extra configuration to enable them to work
- # with groups of projects
- def project_only_application?
- Clusters::Cluster::PROJECT_ONLY_APPLICATIONS.include?(application_name)
- end
-
def application_name
params[:application]
end
diff --git a/app/services/projects/container_repository/delete_tags_service.rb b/app/services/projects/container_repository/delete_tags_service.rb
index 5129e2269a8..6a8b68d8ae3 100644
--- a/app/services/projects/container_repository/delete_tags_service.rb
+++ b/app/services/projects/container_repository/delete_tags_service.rb
@@ -9,25 +9,11 @@ module Projects
tag_names = params[:tags]
return error('not tags specified') if tag_names.blank?
- if can_use?
- smart_delete(container_repository, tag_names)
- else
- unsafe_delete(container_repository, tag_names)
- end
+ smart_delete(container_repository, tag_names)
end
private
- def unsafe_delete(container_repository, tag_names)
- deleted_tags = tag_names.select do |tag_name|
- container_repository.tag(tag_name).unsafe_delete
- end
-
- return error('could not delete tags') if deleted_tags.empty?
-
- success(deleted: deleted_tags)
- end
-
# Replace a tag on the registry with a dummy tag.
# This is a hack as the registry doesn't support deleting individual
# tags. This code effectively pushes a dummy image and assigns the tag to it.
@@ -57,10 +43,6 @@ module Projects
error('could not delete tags')
end
end
-
- def can_use?
- Feature.enabled?(:container_registry_smart_delete, project, default_enabled: true)
- end
end
end
end
diff --git a/app/views/ci/variables/_url_query_variable_row.html.haml b/app/views/ci/variables/_url_query_variable_row.html.haml
new file mode 100644
index 00000000000..6672a8e5ea0
--- /dev/null
+++ b/app/views/ci/variables/_url_query_variable_row.html.haml
@@ -0,0 +1,28 @@
+- form_field = local_assigns.fetch(:form_field, nil)
+- variable = local_assigns.fetch(:variable, nil)
+
+- key = variable[0]
+- value = variable[1]
+- variable_type = variable[2] || "env_var"
+
+- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
+- variable_type_input_name = "#{form_field}[variables_attributes][][variable_type]"
+- key_input_name = "#{form_field}[variables_attributes][][key]"
+- value_input_name = "#{form_field}[variables_attributes][][secret_value]"
+
+%li.js-row.ci-variable-row
+ .ci-variable-row-body.border-bottom
+ %input.js-ci-variable-input-destroy{ type: "hidden", name: destroy_input_name }
+ %select.js-ci-variable-input-variable-type.ci-variable-body-item.form-control.select-control.custom-select.table-section.section-15{ name: variable_type_input_name }
+ = options_for_select(ci_variable_type_options, variable_type)
+ %input.js-ci-variable-input-key.ci-variable-body-item.qa-ci-variable-input-key.form-control.table-section.section-15{ type: "text",
+ name: key_input_name,
+ value: key,
+ placeholder: s_('CiVariables|Input variable key') }
+ .ci-variable-body-item.gl-show-field-errors.table-section.section-15.border-top-0.p-0
+ %textarea.js-ci-variable-input-value.js-secret-value.qa-ci-variable-input-value.form-control{ rows: 1,
+ name: value_input_name,
+ placeholder: s_('CiVariables|Input variable value') }
+ = value
+ %button.js-row-remove-button.ci-variable-row-remove-button.table-section.section-5.border-top-0{ type: 'button', 'aria-label': s_('CiVariables|Remove variable row') }
+ = icon('minus-circle')
diff --git a/app/views/errors/not_found.html.haml b/app/views/errors/not_found.html.haml
index ae055f398ac..13f07e2f5d5 100644
--- a/app/views/errors/not_found.html.haml
+++ b/app/views/errors/not_found.html.haml
@@ -11,5 +11,5 @@
= form_tag search_path, method: :get, class: 'form-inline-flex' do |f|
.field
= search_field_tag :search, '', placeholder: _('Search for projects, issues, etc.'), class: 'form-control'
- = button_tag 'Search', class: 'btn btn-success', name: nil, type: 'submit'
+ = button_tag _('Search'), class: 'btn btn-sm btn-success', name: nil, type: 'submit'
= render 'errors/footer'
diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 68b7efc6fb4..6b27db23315 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -94,7 +94,8 @@
- else
= f.text_field :name, label: s_('Profiles|Full name'), required: true, title: s_("Profiles|Using emojis in names seems fun, but please try to set a status message instead"), wrapper: { class: 'col-md-9 qa-full-name rspec-full-name' }, help: s_("Profiles|Enter your name, so people you know can recognize you")
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
- = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'input-md'
+ - if experiment_enabled?(:signup_flow)
+ = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { prompt: _('Select your role') }, class: 'input-md'
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username")
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index f2215765974..30fe5622ebd 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -19,7 +19,7 @@
= author_avatar(commit, size: 36, has_tooltip: false)
.commit-row-title
%span.item-title.str-truncated-100
- = link_to_markdown commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
+ = link_to commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
.float-right
= link_to commit.short_id, project_commit_path(@project, commit), class: "commit-sha"
&nbsp;
diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml
index bfcaa09ae8c..a3e46a0939c 100644
--- a/app/views/projects/pipelines/new.html.haml
+++ b/app/views/projects/pipelines/new.html.haml
@@ -23,6 +23,13 @@
%label
= s_('Pipeline|Variables')
%ul.ci-variable-list
+ - if params[:var]
+ - params[:var].each do |variable|
+ = render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
+ - if params[:file_var]
+ - params[:file_var].each do |variable|
+ - variable.push("file")
+ = render 'ci/variables/url_query_variable_row', form_field: 'pipeline', variable: variable
= render 'ci/variables/variable_row', form_field: 'pipeline', only_key_value: true
.form-text.text-muted
= (s_("Pipeline|Specify variable values to be used in this run. The values specified in %{settings_link} will be used by default.") % {settings_link: settings_link}).html_safe
diff --git a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
index fb03e6e12e3..3670e19c240 100644
--- a/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
+++ b/app/views/shared/_auto_devops_implicitly_enabled_banner.html.haml
@@ -7,3 +7,7 @@
= link_to _('Settings'), project_settings_ci_cd_path(project), class: 'alert-link'
|
= link_to _('Dismiss'), '#', class: 'hide-auto-devops-implicitly-enabled-banner alert-link', data: { project_id: project.id }
+ - unless Gitlab.config.registry.enabled
+ %div
+ = icon('exclamation-triangle')
+ = _('Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for AutoDevOps to work.')
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 9d580930fb8..2c465bf782f 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -147,6 +147,7 @@
%button.clear-search.hidden{ type: 'button' }
= icon('times')
+ #js-board-labels-toggle
.filter-dropdown-container.d-flex.flex-column.flex-md-row
- if type == :boards
.js-board-config{ data: { can_admin_list: user_can_admin_list, has_scope: board.scoped? } }
diff --git a/changelogs/unreleased/13401-close-gitlab-issue-on-recovery-alerts-from-prometheus.yml b/changelogs/unreleased/13401-close-gitlab-issue-on-recovery-alerts-from-prometheus.yml
new file mode 100644
index 00000000000..466dfd2f50b
--- /dev/null
+++ b/changelogs/unreleased/13401-close-gitlab-issue-on-recovery-alerts-from-prometheus.yml
@@ -0,0 +1,5 @@
+---
+title: Close issues on Prometheus alert recovery
+merge_request: 18431
+author:
+type: added
diff --git a/changelogs/unreleased/24146-query-string-params.yml b/changelogs/unreleased/24146-query-string-params.yml
new file mode 100644
index 00000000000..80cab30e255
--- /dev/null
+++ b/changelogs/unreleased/24146-query-string-params.yml
@@ -0,0 +1,5 @@
+---
+title: Populate new pipeline CI vars from params
+merge_request: 19023
+author:
+type: added
diff --git a/changelogs/unreleased/30161-expose-merge-request-status-in-api.yml b/changelogs/unreleased/30161-expose-merge-request-status-in-api.yml
new file mode 100644
index 00000000000..aaac2d31b0c
--- /dev/null
+++ b/changelogs/unreleased/30161-expose-merge-request-status-in-api.yml
@@ -0,0 +1,5 @@
+---
+title: Expose mergeable state of a merge request
+merge_request: 18888
+author: briankabiro
+type: added
diff --git a/changelogs/unreleased/32198-banner-alerting-of-project-move-is-showing-up-everywhere.yml b/changelogs/unreleased/32198-banner-alerting-of-project-move-is-showing-up-everywhere.yml
new file mode 100644
index 00000000000..a6d211d59ca
--- /dev/null
+++ b/changelogs/unreleased/32198-banner-alerting-of-project-move-is-showing-up-everywhere.yml
@@ -0,0 +1,5 @@
+---
+title: Fix "project or group was moved" alerts showing up in the wrong pages
+merge_request: 18985
+author:
+type: fixed
diff --git a/changelogs/unreleased/backstage-remove-export-designs-feature-flag.yml b/changelogs/unreleased/backstage-remove-export-designs-feature-flag.yml
new file mode 100644
index 00000000000..8e44173ba60
--- /dev/null
+++ b/changelogs/unreleased/backstage-remove-export-designs-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: Removes `export_designs` feature flag
+merge_request: 18507
+author: nate geslin
+type: other
diff --git a/changelogs/unreleased/drop-id-of-ci-trace-sectinos.yml b/changelogs/unreleased/drop-id-of-ci-trace-sectinos.yml
new file mode 100644
index 00000000000..3071269df2c
--- /dev/null
+++ b/changelogs/unreleased/drop-id-of-ci-trace-sectinos.yml
@@ -0,0 +1,5 @@
+---
+title: Drop `id` column from `ci_build_trace_sections` table
+merge_request: 18741
+author:
+type: changed
diff --git a/changelogs/unreleased/dz-ask-users-to-enable-registry.yml b/changelogs/unreleased/dz-ask-users-to-enable-registry.yml
new file mode 100644
index 00000000000..52ea1045fdf
--- /dev/null
+++ b/changelogs/unreleased/dz-ask-users-to-enable-registry.yml
@@ -0,0 +1,5 @@
+---
+title: Add extra sentence about registry to AutoDevOps popup
+merge_request: 19092
+author:
+type: changed
diff --git a/changelogs/unreleased/jc-dont-render-commit-links.yml b/changelogs/unreleased/jc-dont-render-commit-links.yml
new file mode 100644
index 00000000000..6146e354702
--- /dev/null
+++ b/changelogs/unreleased/jc-dont-render-commit-links.yml
@@ -0,0 +1,5 @@
+---
+title: Do not render links in commit message on blame page
+merge_request: 19128
+author:
+type: performance
diff --git a/changelogs/unreleased/lm-search-list-of-sentry-errors.yml b/changelogs/unreleased/lm-search-list-of-sentry-errors.yml
new file mode 100644
index 00000000000..619c2b0c276
--- /dev/null
+++ b/changelogs/unreleased/lm-search-list-of-sentry-errors.yml
@@ -0,0 +1,5 @@
+---
+title: Search list of Sentry errors by title in Gitlab
+merge_request: 18772
+author:
+type: added
diff --git a/changelogs/unreleased/patch-35.yml b/changelogs/unreleased/patch-35.yml
new file mode 100644
index 00000000000..22dce87919a
--- /dev/null
+++ b/changelogs/unreleased/patch-35.yml
@@ -0,0 +1,5 @@
+---
+title: Fix search button height on 404 page
+merge_request: 19080
+author:
+type: fixed
diff --git a/changelogs/unreleased/record-sidekiq-queuing-latency.yml b/changelogs/unreleased/record-sidekiq-queuing-latency.yml
new file mode 100644
index 00000000000..72bacd90e33
--- /dev/null
+++ b/changelogs/unreleased/record-sidekiq-queuing-latency.yml
@@ -0,0 +1,5 @@
+---
+title: Adds a Sidekiq queue duration metric
+merge_request: 19005
+author:
+type: other
diff --git a/changelogs/unreleased/sh-gitaly-duration-measurement.yml b/changelogs/unreleased/sh-gitaly-duration-measurement.yml
new file mode 100644
index 00000000000..60d00e7d9ab
--- /dev/null
+++ b/changelogs/unreleased/sh-gitaly-duration-measurement.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Gitaly call duration measurements
+merge_request: 18785
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-set-httponly-experimentation-subject-id.yml b/changelogs/unreleased/sh-set-httponly-experimentation-subject-id.yml
new file mode 100644
index 00000000000..00cd50d43fd
--- /dev/null
+++ b/changelogs/unreleased/sh-set-httponly-experimentation-subject-id.yml
@@ -0,0 +1,5 @@
+---
+title: Enable the HttpOnly flag for experimentation_subject_id cookie
+merge_request: 19189
+author:
+type: security
diff --git a/config/initializers/rack_attack_git_basic_auth.rb b/config/initializers/rack_attack_git_basic_auth.rb
index 6a721826170..219920b2b19 100644
--- a/config/initializers/rack_attack_git_basic_auth.rb
+++ b/config/initializers/rack_attack_git_basic_auth.rb
@@ -1,14 +1,12 @@
-rack_attack_enabled = Gitlab.config.rack_attack.git_basic_auth['enabled']
+# Tell the Rack::Attack Rack middleware to maintain an IP blacklist.
+# We update the blacklist in Gitlab::Auth::IpRateLimiter.
+Rack::Attack.blocklist('Git HTTP Basic Auth') do |req|
+ next false unless Gitlab.config.rack_attack.git_basic_auth.enabled
-unless Rails.env.test? || !rack_attack_enabled
- # Tell the Rack::Attack Rack middleware to maintain an IP blacklist. We will
- # update the blacklist from Grack::Auth#authenticate_user.
- Rack::Attack.blacklist('Git HTTP Basic Auth') do |req|
- Rack::Attack::Allow2Ban.filter(req.ip, Gitlab.config.rack_attack.git_basic_auth) do
- # This block only gets run if the IP was not already banned.
- # Return false, meaning that we do not see anything wrong with the
- # request at this time
- false
- end
+ Rack::Attack::Allow2Ban.filter(req.ip, Gitlab.config.rack_attack.git_basic_auth) do
+ # This block only gets run if the IP was not already banned.
+ # Return false, meaning that we do not see anything wrong with the
+ # request at this time
+ false
end
end
diff --git a/config/initializers/rack_attack_logging.rb b/config/initializers/rack_attack_logging.rb
index be7c2175cb2..a95cb09755b 100644
--- a/config/initializers/rack_attack_logging.rb
+++ b/config/initializers/rack_attack_logging.rb
@@ -2,8 +2,10 @@
#
# Adds logging for all Rack Attack blocks and throttling events.
-ActiveSupport::Notifications.subscribe('rack.attack') do |name, start, finish, request_id, req|
- if [:throttle, :blacklist].include? req.env['rack.attack.match_type']
+ActiveSupport::Notifications.subscribe(/rack_attack/) do |name, start, finish, request_id, payload|
+ req = payload[:request]
+
+ if [:throttle, :blocklist].include? req.env['rack.attack.match_type']
rack_attack_info = {
message: 'Rack_Attack',
env: req.env['rack.attack.match_type'],
diff --git a/config/puma.example.development.rb b/config/puma.example.development.rb
index f23ccc23c9a..6f686437f88 100644
--- a/config/puma.example.development.rb
+++ b/config/puma.example.development.rb
@@ -14,9 +14,13 @@ rackup 'config.ru'
pidfile '/home/git/gitlab/tmp/pids/puma.pid'
state_path '/home/git/gitlab/tmp/pids/puma.state'
-stdout_redirect '/home/git/gitlab/log/puma.stdout.log',
- '/home/git/gitlab/log/puma.stderr.log',
- true
+## Uncomment the lines if you would like to write puma stdout & stderr streams
+## to a different location than rails logs.
+## When using GitLab Development Kit, by default, these logs will be consumed
+## by runit and can be accessed using `gdk tail rails-web`
+# stdout_redirect '/home/git/gitlab/log/puma.stdout.log',
+# '/home/git/gitlab/log/puma.stderr.log',
+# true
# Configure "min" to be the minimum number of threads to use to answer
# requests and "max" the maximum.
diff --git a/db/migrate/20191003015155_add_self_managed_prometheus_alerts.rb b/db/migrate/20191003015155_add_self_managed_prometheus_alerts.rb
index 94d16e921df..71d10153422 100644
--- a/db/migrate/20191003015155_add_self_managed_prometheus_alerts.rb
+++ b/db/migrate/20191003015155_add_self_managed_prometheus_alerts.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class AddSelfManagedPrometheusAlerts < ActiveRecord::Migration[5.2]
- # Set this constant to true if this migration requires downtime.
DOWNTIME = false
def change
diff --git a/db/post_migrate/20191017180026_drop_ci_build_trace_sections_id.rb b/db/post_migrate/20191017180026_drop_ci_build_trace_sections_id.rb
new file mode 100644
index 00000000000..0405e23b465
--- /dev/null
+++ b/db/post_migrate/20191017180026_drop_ci_build_trace_sections_id.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class DropCiBuildTraceSectionsId < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def up
+ ##
+ # This column has already been ignored since 12.4
+ # See https://gitlab.com/gitlab-org/gitlab/issues/32569
+ remove_column :ci_build_trace_sections, :id
+ end
+
+ def down
+ ##
+ # We don't backfill serial ids as it's not used in application code
+ # and quite expensive process.
+ add_column :ci_build_trace_sections, :id, :bigint
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 31bb3d75ea2..dce9d1dc189 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2019_10_17_094449) do
+ActiveRecord::Schema.define(version: 2019_10_17_180026) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@@ -599,7 +599,7 @@ ActiveRecord::Schema.define(version: 2019_10_17_094449) do
t.index ["project_id", "name"], name: "index_ci_build_trace_section_names_on_project_id_and_name", unique: true
end
- create_table "ci_build_trace_sections", id: :serial, force: :cascade do |t|
+ create_table "ci_build_trace_sections", id: false, force: :cascade do |t|
t.integer "project_id", null: false
t.datetime "date_start", null: false
t.datetime "date_end", null: false
diff --git a/doc/administration/geo/replication/object_storage.md b/doc/administration/geo/replication/object_storage.md
index a9087abcbd9..3251a673e4e 100644
--- a/doc/administration/geo/replication/object_storage.md
+++ b/doc/administration/geo/replication/object_storage.md
@@ -30,7 +30,7 @@ To enable GitLab replication, you must:
checkbox.
For LFS, follow the documentation to
-[set up LFS object storage](../../../workflow/lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
+[set up LFS object storage](../../lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
For CI job artifacts, there is similar documentation to configure
[jobs artifact object storage](../../job_artifacts.md#using-object-storage)
diff --git a/doc/administration/git_annex.md b/doc/administration/git_annex.md
new file mode 100644
index 00000000000..52d848efa27
--- /dev/null
+++ b/doc/administration/git_annex.md
@@ -0,0 +1,242 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/git_annex.html'
+---
+
+# Git annex
+
+> **Warning:** GitLab has [completely
+removed][deprecate-annex-issue] in GitLab 9.0 (2017/03/22).
+Read through the [migration guide from git-annex to Git LFS][guide].
+
+The biggest limitation of Git, compared to some older centralized version
+control systems, has been the maximum size of the repositories.
+
+The general recommendation is to not have Git repositories larger than 1GB to
+preserve performance. Although GitLab has no limit (some repositories in GitLab
+are over 50GB!), we subscribe to the advice to keep repositories as small as
+you can.
+
+Not being able to version control large binaries is a big problem for many
+larger organizations.
+Videos, photos, audio, compiled binaries and many other types of files are too
+large. As a workaround, people keep artwork-in-progress in a Dropbox folder and
+only check in the final result. This results in using outdated files, not
+having a complete history and increases the risk of losing work.
+
+This problem is solved in GitLab Enterprise Edition by integrating the
+[git-annex] application.
+
+`git-annex` allows managing large binaries with Git without checking the
+contents into Git.
+You check-in only a symlink that contains the SHA-1 of the large binary. If you
+need the large binary, you can sync it from the GitLab server over `rsync`, a
+very fast file copying tool.
+
+## GitLab git-annex Configuration
+
+`git-annex` is disabled by default in GitLab. Below you will find the
+configuration options required to enable it.
+
+### Requirements
+
+`git-annex` needs to be installed both on the server and the client side.
+
+For Debian-like systems (e.g., Debian, Ubuntu) this can be achieved by running:
+
+```
+sudo apt-get update && sudo apt-get install git-annex
+```
+
+For RedHat-like systems (e.g., CentOS, RHEL) this can be achieved by running:
+
+```
+sudo yum install epel-release && sudo yum install git-annex
+```
+
+### Configuration for Omnibus packages
+
+For Omnibus GitLab packages, only one configuration setting is needed.
+The Omnibus package will internally set the correct options in all locations.
+
+1. In `/etc/gitlab/gitlab.rb` add the following line:
+
+ ```ruby
+ gitlab_shell['git_annex_enabled'] = true
+ ```
+
+1. Save the file and [reconfigure GitLab][] for the changes to take effect.
+
+### Configuration for installations from source
+
+There are 2 settings to enable git-annex on your GitLab server.
+
+One is located in `config/gitlab.yml` of the GitLab repository and the other
+one is located in `config.yml` of GitLab Shell.
+
+1. In `config/gitlab.yml` add or edit the following lines:
+
+ ```yaml
+ gitlab_shell:
+ git_annex_enabled: true
+ ```
+
+1. In `config.yml` of GitLab Shell add or edit the following lines:
+
+ ```yaml
+ git_annex_enabled: true
+ ```
+
+1. Save the files and [restart GitLab][] for the changes to take effect.
+
+## Using GitLab git-annex
+
+> **Note:**
+> Your Git remotes must be using the SSH protocol, not HTTP(S).
+
+Here is an example workflow of uploading a very large file and then checking it
+into your Git repository:
+
+```bash
+git clone git@example.com:group/project.git
+
+git annex init 'My Laptop' # initialize the annex project and give an optional description
+cp ~/tmp/debian.iso ./ # copy a large file into the current directory
+git annex add debian.iso # add the large file to git annex
+git commit -am "Add Debian iso" # commit the file metadata
+git annex sync --content # sync the Git repo and large file to the GitLab server
+```
+
+The output should look like this:
+
+```
+commit
+On branch master
+Your branch is ahead of 'origin/master' by 1 commit.
+ (use "git push" to publish your local commits)
+nothing to commit, working tree clean
+ok
+pull origin
+remote: Counting objects: 5, done.
+remote: Compressing objects: 100% (4/4), done.
+remote: Total 5 (delta 2), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From example.com:group/project
+ 497842b..5162f80 git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(recording state in git...)
+copy debian.iso (checking origin...) (to origin...)
+SHA256E-s26214400--8092b3d482fb1b7a5cf28c43bc1425c8f2d380e86869c0686c49aa7b0f086ab2.iso
+ 26,214,400 100% 638.88kB/s 0:00:40 (xfr#1, to-chk=0/1)
+ok
+pull origin
+ok
+(recording state in git...)
+push origin
+Counting objects: 15, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (13/13), done.
+Writing objects: 100% (15/15), 1.64 KiB | 0 bytes/s, done.
+Total 15 (delta 1), reused 0 (delta 0)
+To example.com:group/project.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+```
+
+Your files can be found in the `master` branch, but you'll notice that there
+are more branches created by the `annex sync` command.
+
+Git Annex will also create a new directory at `.git/annex/` and will record the
+tracked files in the `.git/config` file. The files you assign to be tracked
+with `git-annex` will not affect the existing `.git/config` records. The files
+are turned into symbolic links that point to data in `.git/annex/objects/`.
+
+The `debian.iso` file in the example will contain the symbolic link:
+
+```
+.git/annex/objects/ZW/1k/SHA256E-s82701--6384039733b5035b559efd5a2e25a493ab6e09aabfd5162cc03f6f0ec238429d.png/SHA256E-s82701--6384039733b5035b559efd5a2e25a493ab6e09aabfd5162cc03f6f0ec238429d.iso
+```
+
+Use `git annex info` to retrieve the information about the local copy of your
+repository.
+
+---
+
+Downloading a single large file is also very simple:
+
+```bash
+git clone git@gitlab.example.com:group/project.git
+
+git annex sync # sync Git branches but not the large file
+git annex get debian.iso # download the large file
+```
+
+To download all files:
+
+```bash
+git clone git@gitlab.example.com:group/project.git
+
+git annex sync --content # sync Git branches and download all the large files
+```
+
+By using `git-annex` without GitLab, anyone that can access the server can also
+access the files of all projects, but GitLab Annex ensures that you can only
+access files of projects you have access to (developer, maintainer, or owner role).
+
+## How it works
+
+Internally GitLab uses [GitLab Shell] to handle SSH access and this was a great
+integration point for `git-annex`.
+There is a setting in GitLab Shell so you can disable GitLab Annex support
+if you want to.
+
+## Troubleshooting tips
+
+Differences in version of `git-annex` on the GitLab server and on local machines
+can cause `git-annex` to raise unpredicted warnings and errors.
+
+Consult the [Annex upgrade page][annex-upgrade] for more information about
+the differences between versions. You can find out which version is installed
+on your server by navigating to <https://pkgs.org/download/git-annex> and
+searching for your distribution.
+
+Although there is no general guide for `git-annex` errors, there are a few tips
+on how to go around the warnings.
+
+### `git-annex-shell: Not a git-annex or gcrypt repository`
+
+This warning can appear on the initial `git annex sync --content` and is caused
+by differences in `git-annex-shell`. You can read more about it
+[in this git-annex issue][issue].
+
+One important thing to note is that despite the warning, the `sync` succeeds
+and the files are pushed to the GitLab repository.
+
+If you get hit by this, you can run the following command inside the repository
+that the warning was raised:
+
+```
+git config remote.origin.annex-ignore false
+```
+
+Consecutive runs of `git annex sync --content` **should not** produce this
+warning and the output should look like this:
+
+```
+commit ok
+pull origin
+ok
+pull origin
+ok
+push origin
+```
+
+[annex-upgrade]: https://git-annex.branchable.com/upgrades/
+[deprecate-annex-issue]: https://gitlab.com/gitlab-org/gitlab/issues/1648
+[git-annex]: https://git-annex.branchable.com/ "git-annex website"
+[gitlab shell]: https://gitlab.com/gitlab-org/gitlab-shell "GitLab Shell repository"
+[guide]: lfs/migrate_from_git_annex_to_git_lfs.html
+[issue]: https://git-annex.branchable.com/forum/Error_from_git-annex-shell_on_creation_of_gcrypt_special_remote/ "git-annex issue"
+[reconfigure GitLab]: restart_gitlab.md#omnibus-gitlab-reconfigure
+[restart GitLab]: restart_gitlab.md#installations-from-source
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 50db86a8e2c..2d5de7e476c 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -551,7 +551,7 @@ a few things that you need to do:
to eliminate the need for a shared authorized_keys file.
1. Configure [object storage for job artifacts](../job_artifacts.md#using-object-storage)
including [incremental logging](../job_logs.md#new-incremental-logging-architecture).
-1. Configure [object storage for LFS objects](../../workflow/lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
+1. Configure [object storage for LFS objects](../lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
1. Configure [object storage for uploads](../uploads.md#using-object-storage-core-only).
NOTE: **Note:**
diff --git a/doc/administration/index.md b/doc/administration/index.md
index e0f8ab8d855..8e616517c28 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -43,7 +43,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
### Configuring GitLab
-- [Adjust your instance's timezone](../workflow/timezone.md): Customize the default time zone of GitLab.
+- [Adjust your instance's timezone](timezone.md): Customize the default time zone of GitLab.
- [System hooks](../system_hooks/system_hooks.md): Notifications when users, projects and keys are changed.
- [Security](../security/README.md): Learn what you can do to further secure your GitLab instance.
- [Usage statistics, version check, and usage ping](../user/admin_area/settings/usage_statistics.md): Enable or disable information about your instance to be sent to GitLab, Inc.
@@ -51,7 +51,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Polling](polling.md): Configure how often the GitLab UI polls for updates.
- [GitLab Pages configuration](pages/index.md): Enable and configure GitLab Pages.
- [GitLab Pages configuration for GitLab source installations](pages/source.md): Enable and configure GitLab Pages on [source installations](../install/installation.md#installation-from-source).
-- [Uploads configuration](uploads.md): Configure GitLab uploads storage.
+- [Uploads administration](uploads.md): Configure GitLab uploads storage.
- [Environment variables](environment_variables.md): Supported environment variables that can be used to override their defaults values in order to configure GitLab.
- [Plugins](plugins.md): With custom plugins, GitLab administrators can introduce custom integrations without modifying GitLab's source code.
- [Enforcing Terms of Service](../user/admin_area/settings/terms.md)
@@ -161,9 +161,10 @@ Learn how to install, configure, update, and maintain your GitLab instance.
## Git configuration options
- [Custom Git hooks](custom_hooks.md): Custom Git hooks (on the filesystem) for when webhooks aren't enough.
-- [Git LFS configuration](../workflow/lfs/lfs_administration.md): Learn how to configure LFS for GitLab.
+- [Git LFS configuration](lfs/lfs_administration.md): Learn how to configure LFS for GitLab.
- [Housekeeping](housekeeping.md): Keep your Git repositories tidy and fast.
- [Configuring Git Protocol v2](git_protocol.md): Git protocol version 2 support.
+- [Manage large files with `git-annex` (Deprecated)](git_annex.md)
## Monitoring GitLab
diff --git a/doc/workflow/lfs/images/git-annex-branches.png b/doc/administration/lfs/img/git-annex-branches.png
index 3d614f68177..3d614f68177 100644
--- a/doc/workflow/lfs/images/git-annex-branches.png
+++ b/doc/administration/lfs/img/git-annex-branches.png
Binary files differ
diff --git a/doc/workflow/lfs/img/lfs-icon.png b/doc/administration/lfs/img/lfs-icon.png
index eef9a14187a..eef9a14187a 100644
--- a/doc/workflow/lfs/img/lfs-icon.png
+++ b/doc/administration/lfs/img/lfs-icon.png
Binary files differ
diff --git a/doc/administration/lfs/lfs_administration.md b/doc/administration/lfs/lfs_administration.md
new file mode 100644
index 00000000000..f3b8029f487
--- /dev/null
+++ b/doc/administration/lfs/lfs_administration.md
@@ -0,0 +1,273 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/lfs/lfs_administration.html'
+---
+
+# GitLab Git LFS Administration
+
+Documentation on how to use Git LFS are under [Managing large binary files with Git LFS doc](manage_large_binaries_with_git_lfs.md).
+
+## Requirements
+
+- Git LFS is supported in GitLab starting with version 8.2.
+- Support for object storage, such as AWS S3, was introduced in 10.0.
+- Users need to install [Git LFS client](https://git-lfs.github.com) version 1.0.1 and up.
+
+## Configuration
+
+Git LFS objects can be large in size. By default, they are stored on the server
+GitLab is installed on.
+
+There are various configuration options to help GitLab server administrators:
+
+- Enabling/disabling Git LFS support
+- Changing the location of LFS object storage
+- Setting up object storage supported by [Fog](http://fog.io/about/provider_documentation.html)
+
+### Configuration for Omnibus installations
+
+In `/etc/gitlab/gitlab.rb`:
+
+```ruby
+# Change to true to enable lfs - enabled by default if not defined
+gitlab_rails['lfs_enabled'] = false
+
+# Optionally, change the storage path location. Defaults to
+# `#{gitlab_rails['shared_path']}/lfs-objects`. Which evaluates to
+# `/var/opt/gitlab/gitlab-rails/shared/lfs-objects` by default.
+gitlab_rails['lfs_storage_path'] = "/mnt/storage/lfs-objects"
+```
+
+### Configuration for installations from source
+
+In `config/gitlab.yml`:
+
+```yaml
+# Change to true to enable lfs
+ lfs:
+ enabled: false
+ storage_path: /mnt/storage/lfs-objects
+```
+
+## Storing LFS objects in remote object storage
+
+> [Introduced][ee-2760] in [GitLab Premium][eep] 10.0. Brought to GitLab Core in 10.7.
+
+It is possible to store LFS objects in remote object storage which allows you
+to offload local hard disk R/W operations, and free up disk space significantly.
+GitLab is tightly integrated with `Fog`, so you can refer to its [documentation](http://fog.io/about/provider_documentation.html)
+to check which storage services can be integrated with GitLab.
+You can also use external object storage in a private local network. For example,
+[MinIO](https://min.io/) is a standalone object storage service, is easy to set up, and works well with GitLab instances.
+
+GitLab provides two different options for the uploading mechanism: "Direct upload" and "Background upload".
+
+**Option 1. Direct upload**
+
+1. User pushes an lfs file to the GitLab instance
+1. GitLab-workhorse uploads the file directly to the external object storage
+1. GitLab-workhorse notifies GitLab-rails that the upload process is complete
+
+**Option 2. Background upload**
+
+1. User pushes an lfs file to the GitLab instance
+1. GitLab-rails stores the file in the local file storage
+1. GitLab-rails then uploads the file to the external object storage asynchronously
+
+The following general settings are supported.
+
+| Setting | Description | Default |
+|---------|-------------|---------|
+| `enabled` | Enable/disable object storage | `false` |
+| `remote_directory` | The bucket name where LFS objects will be stored| |
+| `direct_upload` | Set to true to enable direct upload of LFS without the need of local shared storage. Option may be removed once we decide to support only single storage for all files. | `false` |
+| `background_upload` | Set to false to disable automatic upload. Option may be removed once upload is direct to S3 | `true` |
+| `proxy_download` | Set to true to enable proxying all files served. Option allows to reduce egress traffic as this allows clients to download directly from remote storage instead of proxying all data | `false` |
+| `connection` | Various connection options described below | |
+
+The `connection` settings match those provided by [Fog](https://github.com/fog).
+
+Here is a configuration example with S3.
+
+| Setting | Description | example |
+|---------|-------------|---------|
+| `provider` | The provider name | AWS |
+| `aws_access_key_id` | AWS credentials, or compatible | `ABC123DEF456` |
+| `aws_secret_access_key` | AWS credentials, or compatible | `ABC123DEF456ABC123DEF456ABC123DEF456` |
+| `aws_signature_version` | AWS signature version to use. 2 or 4 are valid options. Digital Ocean Spaces and other providers may need 2. | 4 |
+| `enable_signature_v4_streaming` | Set to true to enable HTTP chunked transfers with [AWS v4 signatures](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be false | true |
+| `region` | AWS region | us-east-1 |
+| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
+| `endpoint` | Can be used when configuring an S3 compatible service such as [MinIO](https://min.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
+| `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false |
+| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false
+
+Here is a configuration example with GCS.
+
+| Setting | Description | example |
+|---------|-------------|---------|
+| `provider` | The provider name | `Google` |
+| `google_project` | GCP project name | `gcp-project-12345` |
+| `google_client_email` | The email address of the service account | `foo@gcp-project-12345.iam.gserviceaccount.com` |
+| `google_json_key_location` | The json key path | `/path/to/gcp-project-12345-abcde.json` |
+
+NOTE: **Note:**
+The service account must have permission to access the bucket.
+[See more](https://cloud.google.com/storage/docs/authentication)
+
+Here is a configuration example with Rackspace Cloud Files.
+
+| Setting | Description | example |
+|---------|-------------|---------|
+| `provider` | The provider name | `Rackspace` |
+| `rackspace_username` | The username of the Rackspace account with access to the container | `joe.smith` |
+| `rackspace_api_key` | The API key of the Rackspace account with access to the container | `ABC123DEF456ABC123DEF456ABC123DE` |
+| `rackspace_region` | The Rackspace storage region to use, a three letter code from the [list of service access endpoints](https://developer.rackspace.com/docs/cloud-files/v1/general-api-info/service-access/) | `iad` |
+| `rackspace_temp_url_key` | The private key you have set in the Rackspace API for temporary URLs. Read more [here](https://developer.rackspace.com/docs/cloud-files/v1/use-cases/public-access-to-your-cloud-files-account/#tempurl) | `ABC123DEF456ABC123DEF456ABC123DE` |
+
+NOTE: **Note:**
+Regardless of whether the container has public access enabled or disabled, Fog will
+use the TempURL method to grant access to LFS objects. If you see errors in logs referencing
+instantiating storage with a temp-url-key, ensure that you have set they key properly
+on the Rackspace API and in `gitlab.rb`. You can verify the value of the key Rackspace
+has set by sending a GET request with token header to the service access endpoint URL
+and comparing the output of the returned headers.
+
+### Manual uploading to an object storage
+
+There are two ways to manually do the same thing as automatic uploading (described above).
+
+**Option 1: rake task**
+
+```sh
+rake gitlab:lfs:migrate
+```
+
+**Option 2: rails console**
+
+```sh
+$ sudo gitlab-rails console # Login to rails console
+
+> # Upload LFS files manually
+> LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object|
+> lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists?
+> end
+```
+
+### S3 for Omnibus installations
+
+On Omnibus installations, the settings are prefixed by `lfs_object_store_`:
+
+1. Edit `/etc/gitlab/gitlab.rb` and add the following lines by replacing with
+ the values you want:
+
+ ```ruby
+ gitlab_rails['lfs_object_store_enabled'] = true
+ gitlab_rails['lfs_object_store_remote_directory'] = "lfs-objects"
+ gitlab_rails['lfs_object_store_connection'] = {
+ 'provider' => 'AWS',
+ 'region' => 'eu-central-1',
+ 'aws_access_key_id' => '1ABCD2EFGHI34JKLM567N',
+ 'aws_secret_access_key' => 'abcdefhijklmnopQRSTUVwxyz0123456789ABCDE',
+ # The below options configure an S3 compatible host instead of AWS
+ 'host' => 'localhost',
+ 'endpoint' => 'http://127.0.0.1:9000',
+ 'path_style' => true
+ }
+ ```
+
+1. Save the file and [reconfigure GitLab]s for the changes to take effect.
+1. Migrate any existing local LFS objects to the object storage:
+
+ ```bash
+ gitlab-rake gitlab:lfs:migrate
+ ```
+
+ This will migrate existing LFS objects to object storage. New LFS objects
+ will be forwarded to object storage unless
+ `gitlab_rails['lfs_object_store_background_upload']` is set to false.
+
+### S3 for installations from source
+
+For source installations the settings are nested under `lfs:` and then
+`object_store:`:
+
+1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following
+ lines:
+
+ ```yaml
+ lfs:
+ enabled: true
+ object_store:
+ enabled: false
+ remote_directory: lfs-objects # Bucket name
+ connection:
+ provider: AWS
+ aws_access_key_id: 1ABCD2EFGHI34JKLM567N
+ aws_secret_access_key: abcdefhijklmnopQRSTUVwxyz0123456789ABCDE
+ region: eu-central-1
+ # Use the following options to configure an AWS compatible host such as Minio
+ host: 'localhost'
+ endpoint: 'http://127.0.0.1:9000'
+ path_style: true
+ ```
+
+1. Save the file and [restart GitLab][] for the changes to take effect.
+1. Migrate any existing local LFS objects to the object storage:
+
+ ```bash
+ sudo -u git -H bundle exec rake gitlab:lfs:migrate RAILS_ENV=production
+ ```
+
+ This will migrate existing LFS objects to object storage. New LFS objects
+ will be forwarded to object storage unless `background_upload` is set to
+ false.
+
+### Migrating back to local storage
+
+In order to migrate back to local storage:
+
+1. Set both `direct_upload` and `background_upload` to false under the LFS object storage settings. Don't forget to restart GitLab.
+1. Run `rake gitlab:lfs:migrate_to_local` on your console.
+1. Disable `object_storage` for LFS objects in `gitlab.rb`. Remember to restart GitLab afterwards.
+
+## Storage statistics
+
+You can see the total storage used for LFS objects on groups and projects
+in the administration area, as well as through the [groups](../../api/groups.md)
+and [projects APIs](../../api/projects.md).
+
+## Troubleshooting: `Google::Apis::TransmissionError: execution expired`
+
+If LFS integration is configred with Google Cloud Storage and background uploads (`background_upload: true` and `direct_upload: false`),
+Sidekiq workers may encouter this error. This is because the uploading timed out with very large files.
+LFS files up to 6Gb can be uploaded without any extra steps, otherwise you need to use the following workaround.
+
+```shell
+$ sudo gitlab-rails console # Login to rails console
+
+> # Set up timeouts. 20 minutes is enough to upload 30GB LFS files.
+> # These settings are only in effect for the same session, i.e. they are not effective for sidekiq workers.
+> ::Google::Apis::ClientOptions.default.open_timeout_sec = 1200
+> ::Google::Apis::ClientOptions.default.read_timeout_sec = 1200
+> ::Google::Apis::ClientOptions.default.send_timeout_sec = 1200
+
+> # Upload LFS files manually. This process does not use sidekiq at all.
+> LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object|
+> lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists?
+> end
+```
+
+See more information in [!19581](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/19581)
+
+## Known limitations
+
+- Support for removing unreferenced LFS objects was added in 8.14 onwards.
+- LFS authentications via SSH was added with GitLab 8.12.
+- Only compatible with the Git LFS client versions 1.1.0 and up, or 1.0.2.
+- The storage statistics currently count each LFS object multiple times for
+ every project linking to it.
+
+[reconfigure gitlab]: ../restart_gitlab.md#omnibus-gitlab-reconfigure "How to reconfigure Omnibus GitLab"
+[restart gitlab]: ../restart_gitlab.md#installations-from-source "How to restart GitLab"
+[eep]: https://about.gitlab.com/pricing/ "GitLab Premium"
+[ee-2760]: https://gitlab.com/gitlab-org/gitlab/merge_requests/2760
diff --git a/doc/administration/lfs/manage_large_binaries_with_git_lfs.md b/doc/administration/lfs/manage_large_binaries_with_git_lfs.md
new file mode 100644
index 00000000000..1fd3077ecb9
--- /dev/null
+++ b/doc/administration/lfs/manage_large_binaries_with_git_lfs.md
@@ -0,0 +1,266 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/lfs/manage_large_binaries_with_git_lfs.html'
+---
+
+# Git LFS
+
+Managing large files such as audio, video and graphics files has always been one
+of the shortcomings of Git. The general recommendation is to not have Git repositories
+larger than 1GB to preserve performance.
+
+![Git LFS tracking status](img/lfs-icon.png)
+
+An LFS icon is shown on files tracked by Git LFS to denote if a file is stored
+as a blob or as an LFS pointer.
+
+## How it works
+
+Git LFS client talks with the GitLab server over HTTPS. It uses HTTP Basic Authentication
+to authorize client requests. Once the request is authorized, Git LFS client receives
+instructions from where to fetch or where to push the large file.
+
+## GitLab server configuration
+
+Documentation for GitLab instance administrators is under [LFS administration doc](lfs_administration.md).
+
+## Requirements
+
+- Git LFS is supported in GitLab starting with version 8.2
+- Git LFS must be enabled under project settings
+- [Git LFS client](https://git-lfs.github.com) version 1.0.1 and up
+
+## Known limitations
+
+- Git LFS v1 original API is not supported since it was deprecated early in LFS
+ development
+- When SSH is set as a remote, Git LFS objects still go through HTTPS
+- Any Git LFS request will ask for HTTPS credentials to be provided so a good Git
+ credentials store is recommended
+- Git LFS always assumes HTTPS so if you have GitLab server on HTTP you will have
+ to add the URL to Git config manually (see [troubleshooting](#troubleshooting))
+
+NOTE: **Note:**
+With 8.12 GitLab added LFS support to SSH. The Git LFS communication
+still goes over HTTP, but now the SSH client passes the correct credentials
+to the Git LFS client, so no action is required by the user.
+
+## Using Git LFS
+
+Lets take a look at the workflow when you need to check large files into your Git
+repository with Git LFS. For example, if you want to upload a very large file and
+check it into your Git repository:
+
+```bash
+git clone git@gitlab.example.com:group/project.git
+git lfs install # initialize the Git LFS project
+git lfs track "*.iso" # select the file extensions that you want to treat as large files
+```
+
+Once a certain file extension is marked for tracking as a LFS object you can use
+Git as usual without having to redo the command to track a file with the same extension:
+
+```bash
+cp ~/tmp/debian.iso ./ # copy a large file into the current directory
+git add . # add the large file to the project
+git commit -am "Added Debian iso" # commit the file meta data
+git push origin master # sync the git repo and large file to the GitLab server
+```
+
+**Make sure** that `.gitattributes` is tracked by Git. Otherwise Git
+LFS will not be working properly for people cloning the project:
+
+```bash
+git add .gitattributes
+```
+
+Cloning the repository works the same as before. Git automatically detects the
+LFS-tracked files and clones them via HTTP. If you performed the `git clone`
+command with a SSH URL, you have to enter your GitLab credentials for HTTP
+authentication.
+
+```bash
+git clone git@gitlab.example.com:group/project.git
+```
+
+If you already cloned the repository and you want to get the latest LFS object
+that are on the remote repository, eg. for a branch from origin:
+
+```bash
+git lfs fetch origin master
+```
+
+### Migrate an existing repo to Git LFS
+
+Read the documentation on how to [migrate an existing Git repo with Git LFS](../../topics/git/migrate_to_git_lfs/index.md).
+
+## File Locking
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/35856) in GitLab 10.5.
+
+The first thing to do before using File Locking is to tell Git LFS which
+kind of files are lockable. The following command will store PNG files
+in LFS and flag them as lockable:
+
+```bash
+git lfs track "*.png" --lockable
+```
+
+After executing the above command a file named `.gitattributes` will be
+created or updated with the following content:
+
+```bash
+*.png filter=lfs diff=lfs merge=lfs -text lockable
+```
+
+You can also register a file type as lockable without using LFS
+(In order to be able to lock/unlock a file you need a remote server that implements the LFS File Locking API),
+in order to do that you can edit the `.gitattributes` file manually:
+
+```bash
+*.pdf lockable
+```
+
+After a file type has been registered as lockable, Git LFS will make
+them readonly on the file system automatically. This means you will
+need to lock the file before editing it.
+
+### Managing Locked Files
+
+Once you're ready to edit your file you need to lock it first:
+
+```bash
+git lfs lock images/banner.png
+Locked images/banner.png
+```
+
+This will register the file as locked in your name on the server:
+
+```bash
+git lfs locks
+images/banner.png joe ID:123
+```
+
+Once you have pushed your changes, you can unlock the file so others can
+also edit it:
+
+```bash
+git lfs unlock images/banner.png
+```
+
+You can also unlock by id:
+
+```bash
+git lfs unlock --id=123
+```
+
+If for some reason you need to unlock a file that was not locked by you,
+you can use the `--force` flag as long as you have a `maintainer` access on
+the project:
+
+```bash
+git lfs unlock --id=123 --force
+```
+
+## Troubleshooting
+
+### error: Repository or object not found
+
+There are a couple of reasons why this error can occur:
+
+- You don't have permissions to access certain LFS object
+
+Check if you have permissions to push to the project or fetch from the project.
+
+- Project is not allowed to access the LFS object
+
+LFS object you are trying to push to the project or fetch from the project is not
+available to the project anymore. Probably the object was removed from the server.
+
+- Local Git repository is using deprecated LFS API
+
+### Invalid status for `<url>` : 501
+
+Git LFS will log the failures into a log file.
+To view this log file, while in project directory:
+
+```bash
+git lfs logs last
+```
+
+If the status `error 501` is shown, it is because:
+
+- Git LFS is not enabled in project settings. Check your project settings and
+ enable Git LFS.
+
+- Git LFS support is not enabled on the GitLab server. Check with your GitLab
+ administrator why Git LFS is not enabled on the server. See
+ [LFS administration documentation](lfs_administration.md) for instructions
+ on how to enable LFS support.
+
+- Git LFS client version is not supported by GitLab server. Check your Git LFS
+ version with `git lfs version`. Check the Git config of the project for traces
+ of deprecated API with `git lfs -l`. If `batch = false` is set in the config,
+ remove the line and try to update your Git LFS client. Only version 1.0.1 and
+ newer are supported.
+
+### getsockopt: connection refused
+
+If you push a LFS object to a project and you receive an error similar to:
+`Post <URL>/info/lfs/objects/batch: dial tcp IP: getsockopt: connection refused`,
+the LFS client is trying to reach GitLab through HTTPS. However, your GitLab
+instance is being served on HTTP.
+
+This behaviour is caused by Git LFS using HTTPS connections by default when a
+`lfsurl` is not set in the Git config.
+
+To prevent this from happening, set the lfs url in project Git config:
+
+```bash
+git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs"
+```
+
+### Credentials are always required when pushing an object
+
+NOTE: **Note:**
+With 8.12 GitLab added LFS support to SSH. The Git LFS communication
+still goes over HTTP, but now the SSH client passes the correct credentials
+to the Git LFS client, so no action is required by the user.
+
+Given that Git LFS uses HTTP Basic Authentication to authenticate the user pushing
+the LFS object on every push for every object, user HTTPS credentials are required.
+
+By default, Git has support for remembering the credentials for each repository
+you use. This is described in [Git credentials man pages](https://git-scm.com/docs/gitcredentials).
+
+For example, you can tell Git to remember the password for a period of time in
+which you expect to push the objects:
+
+```bash
+git config --global credential.helper 'cache --timeout=3600'
+```
+
+This will remember the credentials for an hour after which Git operations will
+require re-authentication.
+
+If you are using OS X you can use `osxkeychain` to store and encrypt your credentials.
+For Windows, you can use `wincred` or Microsoft's [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases).
+
+More details about various methods of storing the user credentials can be found
+on [Git Credential Storage documentation](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage).
+
+### LFS objects are missing on push
+
+GitLab checks files to detect LFS pointers on push. If LFS pointers are detected, GitLab tries to verify that those files already exist in LFS on GitLab.
+
+Verify that LFS in installed locally and consider a manual push with `git lfs push --all`.
+
+If you are storing LFS files outside of GitLab you can disable LFS on the project by setting `lfs_enabled: false` with the [projects API](../../api/projects.md#edit-project).
+
+### Hosting LFS objects externally
+
+It is possible to host LFS objects externally by setting a custom LFS url with `git config -f .lfsconfig lfs.url https://example.com/<project>.git/info/lfs`.
+
+You might choose to do this if you are using an appliance like a Sonatype Nexus to store LFS data. If you choose to use an external LFS store,
+GitLab will not be able to verify LFS objects which means that pushes will fail if you have GitLab LFS support enabled.
+
+To stop push failure, LFS support can be disabled in the [Project settings](../../user/project/settings/index.md). This means you will lose GitLab LFS value-adds (Verifying LFS objects, UI integration for LFS).
diff --git a/doc/administration/lfs/migrate_from_git_annex_to_git_lfs.md b/doc/administration/lfs/migrate_from_git_annex_to_git_lfs.md
new file mode 100644
index 00000000000..cf798472d62
--- /dev/null
+++ b/doc/administration/lfs/migrate_from_git_annex_to_git_lfs.md
@@ -0,0 +1,254 @@
+# Migration guide from Git Annex to Git LFS
+
+>**Note:**
+Git Annex support [has been removed][issue-remove-annex] in GitLab Enterprise
+Edition 9.0 (2017/03/22).
+
+Both [Git Annex][] and [Git LFS][] are tools to manage large files in Git.
+
+## History
+
+Git Annex [was introduced in GitLab Enterprise Edition 7.8][post-3], at a time
+where Git LFS didn't yet exist. A few months later, GitLab brought support for
+Git LFS in [GitLab 8.2][post-2] and is available for both Community and
+Enterprise editions.
+
+## Differences between Git Annex and Git LFS
+
+Some items below are general differences between the two protocols and some are
+ones that GitLab developed.
+
+- Git Annex works only through SSH, whereas Git LFS works both with SSH and HTTPS
+ (SSH support was added in GitLab 8.12).
+- Annex files are stored in a sub-directory of the normal repositories, whereas
+ LFS files are stored outside of the repositories in a place you can define.
+- Git Annex requires a more complex setup, but has much more options than Git
+ LFS. You can compare the commands each one offers by running `man git-annex`
+ and `man git-lfs`.
+- Annex files cannot be browsed directly in GitLab's interface, whereas LFS
+ files can.
+
+## Migration steps
+
+>**Note:**
+Since Git Annex files are stored in a sub-directory of the normal repositories
+(`.git/annex/objects`) and LFS files are stored outside of the repositories,
+they are not compatible as they are using a different scheme. Therefore, the
+migration has to be done manually per repository.
+
+There are basically two steps you need to take in order to migrate from Git
+Annex to Git LFS.
+
+### TL; DR
+
+If you know what you are doing and want to skip the reading, this is what you
+need to do (we assume you have [git-annex enabled](../git_annex.md#using-gitlab-git-annex) in your
+repository and that you have made backups in case something goes wrong).
+Fire up a terminal, navigate to your Git repository and:
+
+1. Disable `git-annex`:
+
+ ```bash
+ git annex sync --content
+ git annex direct
+ git annex uninit
+ git annex indirect
+ ```
+
+1. Enable `git-lfs`:
+
+ ```
+ git lfs install
+ git lfs track <files>
+ git add .
+ git commit -m "commit message"
+ git push
+ ```
+
+### Disabling Git Annex in your repo
+
+Before changing anything, make sure you have a backup of your repository first.
+There are a couple of ways to do that, but you can simply clone it to another
+local path and maybe push it to GitLab if you want a remote backup as well.
+Here you'll find a guide on
+[how to back up a **git-annex** repository to an external hard drive][bkp-ext-drive].
+
+Since Annex files are stored as objects with symlinks and cannot be directly
+modified, we need to first remove those symlinks.
+
+NOTE: **Note:**
+Make sure the you read about the [`direct` mode][annex-direct] as it contains
+useful information that may fit in your use case. Note that `annex direct` is
+deprecated in Git Annex version 6, so you may need to upgrade your repository
+if the server also has Git Annex 6 installed. Read more in the
+[Git Annex troubleshooting tips](../git_annex.md#troubleshooting-tips) section.
+
+1. Backup your repository
+
+ ```bash
+ cd repository
+ git annex sync --content
+ cd ..
+ git clone repository repository-backup
+ cd repository-backup
+ git annex get
+ cd ..
+ ```
+
+1. Use `annex direct`:
+
+ ```bash
+ cd repository
+ git annex direct
+ ```
+
+ The output should be similar to this:
+
+ ```bash
+ commit
+ On branch master
+ Your branch is up-to-date with 'origin/master'.
+ nothing to commit, working tree clean
+ ok
+ direct debian.iso ok
+ direct ok
+ ```
+
+1. Disable Git Annex with [`annex uninit`][uninit]:
+
+ ```bash
+ git annex uninit
+ ```
+
+ The output should be similar to this:
+
+ ```bash
+ unannex debian.iso ok
+ Deleted branch git-annex (was 2534d2c).
+ ```
+
+ This will `unannex` every file in the repository, leaving the original files.
+
+1. Switch back to `indirect` mode:
+
+ ```bash
+ git annex indirect
+ ```
+
+ The output should be similar to this:
+
+ ```bash
+ (merging origin/git-annex into git-annex...)
+ (recording state in git...)
+ commit (recording state in git...)
+
+ ok
+ (recording state in git...)
+ [master fac3194] commit before switching to indirect mode
+ 1 file changed, 1 deletion(-)
+ delete mode 120000 alpine-virt-3.4.4-x86_64.iso
+ ok
+ indirect ok
+ ok
+ ```
+
+---
+
+At this point, you have two options. Either add, commit and push the files
+directly back to GitLab or switch to Git LFS. We will tackle the LFS switch in
+the next section.
+
+### Enabling Git LFS in your repo
+
+Git LFS is enabled by default on all GitLab products (GitLab CE, GitLab EE,
+GitLab.com), therefore, you don't need to do anything server-side.
+
+1. First, make sure you have `git-lfs` installed locally:
+
+ ```bash
+ git lfs help
+ ```
+
+ If the terminal doesn't prompt you with a full response on `git-lfs` commands,
+ [install the Git LFS client][install-lfs] first.
+
+1. Inside the repo, run the following command to initiate LFS:
+
+ ```bash
+ git lfs install
+ ```
+
+1. Enable `git-lfs` for the group of files you want to track. You
+ can track specific files, all files containing the same extension, or an
+ entire directory:
+
+ ```bash
+ git lfs track images/01.png # per file
+ git lfs track **/*.png # per extension
+ git lfs track images/ # per directory
+ ```
+
+ Once you do that, run `git status` and you'll see `.gitattributes` added
+ to your repo. It collects all file patterns that you chose to track via
+ `git-lfs`.
+
+1. Add the files, commit and push them to GitLab:
+
+ ```bash
+ git add .
+ git commit -m "commit message"
+ git push
+ ```
+
+ If your remote is set up with HTTP, you will be asked to enter your login
+ credentials. If you have [2FA enabled](../../user/profile/account/two_factor_authentication.md), make sure to use a
+ [personal access token](../../user/profile/account/two_factor_authentication.md#personal-access-tokens)
+ instead of your password.
+
+## Removing the Git Annex branches
+
+After the migration finishes successfully, you can remove all `git-annex`
+related branches from your repository.
+
+On GitLab, navigate to your project's **Repository ➔ Branches** and delete all
+branches created by Git Annex: `git-annex`, and all under `synced/`.
+
+![repository branches](img/git-annex-branches.png)
+
+You can also do this on the command line with:
+
+```bash
+git branch -d synced/master
+git branch -d synced/git-annex
+git push origin :synced/master
+git push origin :synced/git-annex
+git push origin :git-annex
+git remote prune origin
+```
+
+If there are still some Annex objects inside your repository (`.git/annex/`)
+or references inside `.git/config`, run `annex uninit` again:
+
+```bash
+git annex uninit
+```
+
+## Further Reading
+
+- (Blog Post) [Getting Started with Git FLS][post-1]
+- (Blog Post) [Announcing LFS Support in GitLab][post-2]
+- (Blog Post) [GitLab Annex Solves the Problem of Versioning Large Binaries with Git][post-3]
+- (GitLab Docs) [Git Annex](../git_annex.md)
+- (GitLab Docs) [Git LFS](manage_large_binaries_with_git_lfs.md)
+
+[annex-direct]: https://git-annex.branchable.com/direct_mode/
+[bkp-ext-drive]: https://www.thomas-krenn.com/en/wiki/Git-annex_Repository_on_an_External_Hard_Drive
+[Git Annex]: http://git-annex.branchable.com/
+[Git LFS]: https://git-lfs.github.com/
+[install-lfs]: https://git-lfs.github.com/
+[issue-remove-annex]: https://gitlab.com/gitlab-org/gitlab/issues/1648
+[lfs-track]: https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/#tracking-files-with-lfs
+[post-1]: https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/
+[post-2]: https://about.gitlab.com/blog/2015/11/23/announcing-git-lfs-support-in-gitlab/
+[post-3]: https://about.gitlab.com/blog/2015/02/17/gitlab-annex-solves-the-problem-of-versioning-large-binaries-with-git/
+[uninit]: https://git-annex.branchable.com/git-annex-uninit/
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index a0b77c38205..a52b6227e14 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -54,7 +54,7 @@ Make sure _Enable the Performance Bar_ is checked and hit
**Save** to save the changes.
Once the Performance Bar is enabled, you will need to press the [<kbd>p</kbd> +
-<kbd>b</kbd> keyboard shortcut](../../../workflow/shortcuts.md) to actually
+<kbd>b</kbd> keyboard shortcut](../../../user/shortcuts.md) to actually
display it.
You can toggle the Bar using the same shortcut.
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index f6f0222270f..9c7b5bc6b87 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -183,7 +183,8 @@ CI Artifacts are S3 compatible since **9.4** (GitLab Premium), and available in
##### LFS Objects
-LFS Objects implements a similar storage pattern using 2 chars, 2 level folders, following Git own implementation:
+[LFS Objects in GitLab](lfs/manage_large_binaries_with_git_lfs.md) implement a similar
+storage pattern using 2 chars, 2 level folders, following Git's own implementation:
```ruby
"shared/lfs-objects/#{oid[0..1}/#{oid[2..3]}/#{oid[4..-1]}"
@@ -192,7 +193,7 @@ LFS Objects implements a similar storage pattern using 2 chars, 2 level folders,
"shared/lfs-objects/89/09/029eb962194cfb326259411b22ae3f4a814b5be4f80651735aeef9f3229c"
```
-They are also S3 compatible since **10.0** (GitLab Premium), and available in GitLab Core since **10.7**.
+LFS objects are also [S3 compatible](lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
[ce-2821]: https://gitlab.com/gitlab-com/infrastructure/issues/2821
[ce-28283]: https://gitlab.com/gitlab-org/gitlab-foss/issues/28283
diff --git a/doc/administration/timezone.md b/doc/administration/timezone.md
new file mode 100644
index 00000000000..3594ba19181
--- /dev/null
+++ b/doc/administration/timezone.md
@@ -0,0 +1,37 @@
+# Changing your time zone
+
+The global time zone configuration parameter can be changed in `config/gitlab.yml`:
+
+```text
+# time_zone: 'UTC'
+```
+
+Uncomment and customize if you want to change the default time zone of the GitLab application.
+
+## Viewing available timezones
+
+To see all available time zones, run `bundle exec rake time:zones:all`.
+
+For Omnibus installations, run `gitlab-rake time:zones:all`.
+
+NOTE: **Note:**
+Currently, this rake task does not list timezones in TZInfo format required by GitLab Omnibus during a reconfigure: [#58672](https://gitlab.com/gitlab-org/gitlab-foss/issues/58672).
+
+## Changing time zone in Omnibus installations
+
+GitLab defaults its time zone to UTC. It has a global timezone configuration parameter in `/etc/gitlab/gitlab.rb`.
+
+To obtain a list of timezones, log in to your GitLab application server and run a command that generates a list of timezones in TZInfo format for the server. For example, install `timedatectl` and run `timedatectl list-timezones`.
+
+To update, add the timezone that best applies to your location. For example:
+
+```ruby
+gitlab_rails['time_zone'] = 'America/New_York'
+```
+
+After adding the configuration parameter, reconfigure and restart your GitLab instance:
+
+```sh
+gitlab-ctl reconfigure
+gitlab-ctl restart
+```
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 4bc46c3030d..ef5cbeb015e 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -304,7 +304,9 @@ Parameters:
"task_completion_status":{
"count":0,
"completed_count":0
- }
+ },
+ "has_conflicts": false,
+ "blocking_discussions_resolved": true
}
]
```
@@ -453,7 +455,9 @@ Parameters:
"task_completion_status":{
"count":0,
"completed_count":0
- }
+ },
+ "has_conflicts": false,
+ "blocking_discussions_resolved": true
}
]
```
@@ -606,7 +610,9 @@ Parameters:
"task_completion_status":{
"count":0,
"completed_count":0
- }
+ },
+ "has_conflicts": false,
+ "blocking_discussions_resolved": true
}
```
diff --git a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
index 54b21939116..dd474b09a9c 100644
--- a/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/bitbucket_integration.md
@@ -151,7 +151,7 @@ To use GitLab CI/CD with a Bitbucket Cloud repository:
GitLab is now configured to mirror changes from Bitbucket, run CI/CD pipelines
configured in `.gitlab-ci.yml` and push the status to Bitbucket.
-[pull-mirroring]: ../../workflow/repository_mirroring.md#pulling-from-a-remote-repository-starter
+[pull-mirroring]: ../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter
<!-- ## Troubleshooting
diff --git a/doc/ci/ci_cd_for_external_repos/github_integration.md b/doc/ci/ci_cd_for_external_repos/github_integration.md
index 08660b014b0..a290e9adbe9 100644
--- a/doc/ci/ci_cd_for_external_repos/github_integration.md
+++ b/doc/ci/ci_cd_for_external_repos/github_integration.md
@@ -46,7 +46,7 @@ repositories:
GitLab will:
1. Import the project.
-1. Enable [Pull Mirroring](../../workflow/repository_mirroring.md#pulling-from-a-remote-repository-starter)
+1. Enable [Pull Mirroring](../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter)
1. Enable [GitHub project integration](../../user/project/integrations/github.md)
1. Create a web hook on GitHub to notify GitLab of new commits.
diff --git a/doc/ci/ci_cd_for_external_repos/index.md b/doc/ci/ci_cd_for_external_repos/index.md
index 35e2117c285..0039c40dcd3 100644
--- a/doc/ci/ci_cd_for_external_repos/index.md
+++ b/doc/ci/ci_cd_for_external_repos/index.md
@@ -101,5 +101,5 @@ requests and not on branches you can add `except: [branches]` to the job specs.
[ee-4642]: https://gitlab.com/gitlab-org/gitlab/merge_requests/4642
[eep]: https://about.gitlab.com/pricing/
-[mirroring]: ../../workflow/repository_mirroring.md
+[mirroring]: ../../user/project/repository/repository_mirroring.md
[settings]: ../../user/project/settings/index.md#sharing-and-permissions
diff --git a/doc/ci/docker/using_docker_build.md b/doc/ci/docker/using_docker_build.md
index f4bb7cd7d9f..8aa90d43b83 100644
--- a/doc/ci/docker/using_docker_build.md
+++ b/doc/ci/docker/using_docker_build.md
@@ -728,14 +728,18 @@ is set to `always`.
[2fa]: ../../user/profile/account/two_factor_authentication.md
[pat]: ../../user/profile/personal_access_tokens.md
-<!-- ## Troubleshooting
+## Troubleshooting
-Include any troubleshooting steps that you can foresee. If you know beforehand what issues
-one might have when setting this up, or when something is changed, or on upgrading, it's
-important to describe those, too. Think of things that may go wrong and include them here.
-This is important to minimize requests for support, and to avoid doc comments with
-questions that you know someone might ask.
+### docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
-Each scenario can be a third-level heading, e.g. `### Getting error message X`.
-If you have none to add when creating a doc, leave this section in place
-but commented out to help encourage others to add to it in the future. -->
+This is a common error when you are using
+[Docker in Docker](#use-docker-in-docker-workflow-with-docker-executor)
+v19.03 or higher.
+
+This occurs because Docker starts on TLS automatically, so you need to do some set up.
+If:
+
+- This is the first time setting it up, carefully read
+ [using Docker in Docker workflow](#use-docker-in-docker-workflow-with-docker-executor).
+- You are upgrading from v18.09 or earlier, read our
+ [upgrade guide](https://about.gitlab.com/blog/2019/07/31/docker-in-docker-with-docker-19-dot-03/).
diff --git a/doc/ci/environments.md b/doc/ci/environments.md
index cef95c8e22a..cd6f810674b 100644
--- a/doc/ci/environments.md
+++ b/doc/ci/environments.md
@@ -292,7 +292,7 @@ For the value of:
the web server to serve these requests is based on your setup.
We have used `$CI_ENVIRONMENT_SLUG` here because it is guaranteed to be unique. If
- you're using a workflow like [GitLab Flow](../workflow/gitlab_flow.md), collisions
+ you're using a workflow like [GitLab Flow](../topics/gitlab_flow.md), collisions
are unlikely and you may prefer environment names to be more closely based on the
branch name. In that case, you could use `$CI_COMMIT_REF_SLUG` in `environment:url` in
the example above: `https://$CI_COMMIT_REF_SLUG.example.com`, which would give a URL
diff --git a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
index a7ed4ca3514..5acdd273548 100644
--- a/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
+++ b/doc/ci/examples/laravel_with_gitlab_and_envoy/index.md
@@ -379,7 +379,7 @@ These are persistent data and will be shared to every new release.
Now, we would need to deploy our app by running `envoy run deploy`, but it won't be necessary since GitLab can handle that for us with CI's [environments](../../environments.md), which will be described [later](#setting-up-gitlab-cicd) in this tutorial.
Now it's time to commit [Envoy.blade.php](https://gitlab.com/mehranrasulian/laravel-sample/blob/master/Envoy.blade.php) and push it to the `master` branch.
-To keep things simple, we commit directly to `master`, without using [feature-branches](../../../workflow/gitlab_flow.md#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial.
+To keep things simple, we commit directly to `master`, without using [feature-branches](../../../topics/gitlab_flow.md#github-flow-as-a-simpler-alternative) since collaboration is beyond the scope of this tutorial.
In a real world project, teams may use [Issue Tracker](../../../user/project/issues/index.md) and [Merge Requests](../../../user/project/merge_requests/index.md) to move their code across branches:
```bash
diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md
index e5f2701c6ae..a8d785fe184 100644
--- a/doc/ci/pipelines.md
+++ b/doc/ci/pipelines.md
@@ -28,7 +28,7 @@ If all the jobs in a stage:
- Fail, the next stage is not (usually) executed and the pipeline ends early.
NOTE: **Note:**
-If you have a [mirrored repository that GitLab pulls from](../workflow/repository_mirroring.md#pulling-from-a-remote-repository-starter),
+If you have a [mirrored repository that GitLab pulls from](../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter),
you may need to enable pipeline triggering in your project's
**Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates**.
diff --git a/doc/ci/quick_start/README.md b/doc/ci/quick_start/README.md
index 10a898be900..67e93174e2d 100644
--- a/doc/ci/quick_start/README.md
+++ b/doc/ci/quick_start/README.md
@@ -143,7 +143,7 @@ Now if you go to the **Pipelines** page you will see that the pipeline is
pending.
NOTE: **Note:**
-If you have a [mirrored repository where GitLab pulls from](../../workflow/repository_mirroring.md#pulling-from-a-remote-repository-starter),
+If you have a [mirrored repository where GitLab pulls from](../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter),
you may need to enable pipeline triggering in your project's
**Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates**.
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 5d86d382aa8..bc0b6da45a9 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -54,25 +54,37 @@ or directly in the `.gitlab-ci.yml` file and reuse them as you wish.
That can be very powerful as it can be used for scripting without
the need to specify the value itself.
-#### Variable types
+#### Types of variables
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/46806) in GitLab 11.11.
There are two types of variables supported by GitLab:
-- "Variable": the Runner will create an environment variable named same as the variable key and set its value to the variable value.
-- "File": the Runner will write the variable value to a temporary file and set the path to this file as the value of an environment variable named same as the variable key.
+- [Variable type](#variable-type): The Runner will create an environment variable named the same as the
+ variable key and set its value to the variable value.
+- [File type](#file-type): The Runner will write the variable value to a temporary file and set the
+ path to this file as the value of an environment variable, named the same as the variable key.
-Many tools (like [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html) and [kubectl](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable)) provide the ability to customise configuration using files by either providing the file path as a command line argument or an environment variable. Prior to the introduction of variable types, the common pattern was to use the value of a CI variable, save it in a file, and then use the newly created file in your script:
+##### Variable type
+
+Many tools (like [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)
+and [kubectl](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#the-kubeconfig-environment-variable))
+provide the ability to customise configuration using files by either providing the
+file path as a command line argument or an environment variable. In the past, the
+common pattern was to read the value of a CI variable, save it in a file, and then
+use the newly created file in your script:
```bash
-# Save the content of variable in a file
+# Read certificate stored in $KUBE_CA_PEM variable and save it in a new file
echo "$KUBE_CA_PEM" > "$(pwd)/kube.ca.pem"
- # Use the newly created file
+# Pass the newly created file to kubectl
kubectl config set-cluster e2e --server="$KUBE_URL" --certificate-authority="$(pwd)/kube.ca.pem"
```
-This can be simplified by creating a variable of type "File" and using it directly. For example, let's say we have the following variables.
+##### File type
+
+The example above can now be simplified by creating a "File" type variable, and using
+it directly. For example, let's say we have the following variables:
![CI/CD settings - variable types usage example](img/variable_types_usage_example.png)
diff --git a/doc/ci/variables/deprecated_variables.md b/doc/ci/variables/deprecated_variables.md
index cdca5bf27fc..543da481938 100644
--- a/doc/ci/variables/deprecated_variables.md
+++ b/doc/ci/variables/deprecated_variables.md
@@ -20,15 +20,15 @@ future GitLab releases.**
| 8.x name | 9.0+ name |
| --------------------- |------------------------ |
+| `CI_BUILD_BEFORE_SHA` | `CI_COMMIT_BEFORE_SHA` |
| `CI_BUILD_ID` | `CI_JOB_ID` |
+| `CI_BUILD_MANUAL` | `CI_JOB_MANUAL` |
+| `CI_BUILD_NAME` | `CI_JOB_NAME` |
| `CI_BUILD_REF` | `CI_COMMIT_SHA` |
-| `CI_BUILD_TAG` | `CI_COMMIT_TAG` |
-| `CI_BUILD_BEFORE_SHA` | `CI_COMMIT_BEFORE_SHA` |
| `CI_BUILD_REF_NAME` | `CI_COMMIT_REF_NAME` |
| `CI_BUILD_REF_SLUG` | `CI_COMMIT_REF_SLUG` |
-| `CI_BUILD_NAME` | `CI_JOB_NAME` |
-| `CI_BUILD_STAGE` | `CI_JOB_STAGE` |
| `CI_BUILD_REPO` | `CI_REPOSITORY_URL` |
-| `CI_BUILD_TRIGGERED` | `CI_PIPELINE_TRIGGERED` |
-| `CI_BUILD_MANUAL` | `CI_JOB_MANUAL` |
+| `CI_BUILD_STAGE` | `CI_JOB_STAGE` |
+| `CI_BUILD_TAG` | `CI_COMMIT_TAG` |
| `CI_BUILD_TOKEN` | `CI_JOB_TOKEN` |
+| `CI_BUILD_TRIGGERED` | `CI_PIPELINE_TRIGGERED` |
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index 242367db2ef..28c6bc6c418 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -23,7 +23,7 @@ We have complete examples of configuring pipelines:
- To see a large `.gitlab-ci.yml` file used in an enterprise, see the [`.gitlab-ci.yml` file for `gitlab`](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab-ci.yml).
NOTE: **Note:**
-If you have a [mirrored repository where GitLab pulls from](../../workflow/repository_mirroring.md#pulling-from-a-remote-repository-starter),
+If you have a [mirrored repository where GitLab pulls from](../../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter),
you may need to enable pipeline triggering in your project's
**Settings > Repository > Pull from a remote repository > Trigger pipelines for mirror updates**.
diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md
index 86f17f4ecdb..b9d55a9395c 100644
--- a/doc/development/contributing/merge_request_workflow.md
+++ b/doc/development/contributing/merge_request_workflow.md
@@ -36,7 +36,7 @@ include a regression test are merged quickly, while new features without proper
tests might be slower to receive feedback. The workflow to make a merge
request is as follows:
-1. [Fork](../../workflow/forking_workflow.md#creating-a-fork) the project into
+1. [Fork](../../user/project/repository/forking_workflow.md) the project into
your personal namespace (or group) on GitLab.com.
1. Create a feature branch in your fork (don't work off `master`).
1. Write [tests](../rake_tasks.md#run-tests) and code.
diff --git a/doc/development/git_object_deduplication.md b/doc/development/git_object_deduplication.md
index e8af6346524..6d9eb90d482 100644
--- a/doc/development/git_object_deduplication.md
+++ b/doc/development/git_object_deduplication.md
@@ -1,6 +1,6 @@
# How Git object deduplication works in GitLab
-When a GitLab user [forks a project](../workflow/forking_workflow.md),
+When a GitLab user [forks a project](../user/project/repository/forking_workflow.md),
GitLab creates a new Project with an associated Git repository that is a
copy of the original project at the time of the fork. If a large project
gets forked often, this can lead to a quick increase in Git repository
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index cd23ab9226f..8d83cea8c7b 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -15,6 +15,8 @@ as much as possible.
The current stages are:
+- `sync`: This stage is used to synchronize changes from gitlab-org/gitlab to
+ gitlab-org/gitlab-foss.
- `prepare`: This stage includes jobs that prepare artifacts that are needed by
jobs in subsequent stages.
- `quick-test`: This stage includes test jobs that should run first and fail the
diff --git a/doc/development/repository_mirroring.md b/doc/development/repository_mirroring.md
index 8521d6fcd30..0a0c91821cf 100644
--- a/doc/development/repository_mirroring.md
+++ b/doc/development/repository_mirroring.md
@@ -5,6 +5,6 @@
In December 2018, Tiago Botelho hosted a [Deep Dive] on GitLab's [Pull Repository Mirroring functionality] to share his domain specific knowledge with anyone who may work in this part of the code base in the future. You can find the [recording on YouTube], and the slides in [PDF]. Everything covered in this deep dive was accurate as of GitLab 11.6, and while specific details may have changed since then, it should still serve as a good introduction.
[Deep Dive]: https://gitlab.com/gitlab-org/create-stage/issues/1
-[Pull Repository Mirroring functionality]: ../workflow/repository_mirroring.md#pulling-from-a-remote-repository-starter
+[Pull Repository Mirroring functionality]: ../user/project/repository/repository_mirroring.md#pulling-from-a-remote-repository-starter
[recording on YouTube]: https://www.youtube.com/watch?v=sSZq0fpdY-Y
[PDF]: https://gitlab.com/gitlab-org/create-stage/uploads/8693404888a941fd851f8a8ecdec9675/Gitlab_Create_-_Pull_Mirroring_Deep_Dive.pdf
diff --git a/doc/gitlab-basics/README.md b/doc/gitlab-basics/README.md
index fc3d36910f2..258a85d0474 100644
--- a/doc/gitlab-basics/README.md
+++ b/doc/gitlab-basics/README.md
@@ -23,6 +23,7 @@ The following are guides to basic GitLab functionality:
- [Create a group](../user/group/index.md#create-a-new-group), to combine and administer
projects together.
- [Create a branch](create-branch.md), to make changes to files stored in a project's repository.
+- [Feature branch workflow](feature_branch_workflow.md).
- [Fork a project](fork-project.md), to duplicate projects so they can be worked on in parallel.
- [Add a file](add-file.md), to add new files to a project's repository.
- [Create an issue](../user/project/issues/managing_issues.md#create-a-new-issue),
@@ -30,7 +31,7 @@ The following are guides to basic GitLab functionality:
- [Create a merge request](add-merge-request.md), to request changes made in a branch
be merged into a project's repository.
- See how these features come together in the [GitLab Flow introduction video](https://youtu.be/InKNIvky2KE)
- and [GitLab Flow page](../workflow/gitlab_flow.md).
+ and [GitLab Flow page](../topics/gitlab_flow.md).
## Working with Git from the command line
diff --git a/doc/gitlab-basics/feature_branch_workflow.md b/doc/gitlab-basics/feature_branch_workflow.md
new file mode 100644
index 00000000000..2b641126d0d
--- /dev/null
+++ b/doc/gitlab-basics/feature_branch_workflow.md
@@ -0,0 +1,35 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/workflow.html'
+---
+
+# Feature branch workflow
+
+1. Clone project:
+
+ ```bash
+ git clone git@example.com:project-name.git
+ ```
+
+1. Create branch with your feature:
+
+ ```bash
+ git checkout -b $feature_name
+ ```
+
+1. Write code. Commit changes:
+
+ ```bash
+ git commit -am "My feature is ready"
+ ```
+
+1. Push your branch to GitLab:
+
+ ```bash
+ git push origin $feature_name
+ ```
+
+1. Review your code on commits page.
+
+1. Create a merge request.
+
+1. Your team lead will review the code &amp; merge it to the main branch.
diff --git a/doc/gitlab-basics/fork-project.md b/doc/gitlab-basics/fork-project.md
index 5c19985121d..e92491a0821 100644
--- a/doc/gitlab-basics/fork-project.md
+++ b/doc/gitlab-basics/fork-project.md
@@ -8,4 +8,4 @@ A fork is a copy of an original repository that you put in another namespace
where you can experiment and apply changes that you can later decide whether or
not to share, without affecting the original project.
-It takes just a few steps to [fork a project in GitLab](../workflow/forking_workflow.md#creating-a-fork).
+It takes just a few steps to [fork a project in GitLab](../user/project/repository/forking_workflow.md#creating-a-fork).
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index 2dea763688e..c1dde05196c 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -539,7 +539,7 @@ which would otherwise take much space.
In particular, you can store in S3:
-- [The Git LFS objects](../../workflow/lfs/lfs_administration.md#s3-for-omnibus-installations) ((Omnibus GitLab installations))
+- [The Git LFS objects](../../administration/lfs/lfs_administration.md#s3-for-omnibus-installations) ((Omnibus GitLab installations))
- [The Container Registry images](../../administration/packages/container_registry.md#container-registry-storage-driver) (Omnibus GitLab installations)
- [The GitLab CI/CD job artifacts](../../administration/job_artifacts.md#using-object-storage) (Omnibus GitLab installations)
diff --git a/doc/intro/README.md b/doc/intro/README.md
index 33b23372280..3115e3bdb1e 100644
--- a/doc/intro/README.md
+++ b/doc/intro/README.md
@@ -24,7 +24,7 @@ Create issues, labels, milestones, cast your vote, and review issues.
Create merge requests and review code.
-- [Fork a project and contribute to it](../workflow/forking_workflow.md)
+- [Fork a project and contribute to it](../user/project/repository/forking_workflow.md)
- [Create a new merge request](../gitlab-basics/add-merge-request.md)
- [Automatically close issues from merge requests](../user/project/issues/managing_issues.md#closing-issues-automatically)
- [Automatically merge when pipeline succeeds](../user/project/merge_requests/merge_when_pipeline_succeeds.md)
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index fe9617c75ad..006e998b1ab 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -877,7 +877,7 @@ including (but not restricted to):
- [Custom Pages domains](../user/project/pages/custom_domains_ssl_tls_certification/index.md)
- [Project error tracking](../user/project/operations/error_tracking.md)
- [Runner authentication](../ci/runners/README.md)
-- [Project mirroring](../workflow/repository_mirroring.md)
+- [Project mirroring](../user/project/repository/repository_mirroring.md)
- [Web hooks](../user/project/integrations/webhooks.md)
In cases like CI/CD variables and Runner authentication, you might
diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md
index d9bdd73221f..2d3576f6022 100644
--- a/doc/topics/autodevops/quick_start_guide.md
+++ b/doc/topics/autodevops/quick_start_guide.md
@@ -212,7 +212,7 @@ under **Settings > CI/CD > Environment variables**.
### Working with branches
-Following the [GitLab flow](../../workflow/gitlab_flow.md#working-with-feature-branches),
+Following the [GitLab flow](../gitlab_flow.md#working-with-feature-branches),
let's create a feature branch that will add some content to the application.
Under your repository, navigate to the following file: `app/views/welcome/index.html.erb`.
diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md
index d6e1f83b876..7a8b11d2b07 100644
--- a/doc/topics/git/index.md
+++ b/doc/topics/git/index.md
@@ -32,7 +32,7 @@ The following resources will help you get started with Git:
- Commits:
- [Revert a commit](../../user/project/merge_requests/revert_changes.md#reverting-a-commit)
- [Cherry-picking a commit](../../user/project/merge_requests/cherry_pick_changes.md#cherry-picking-a-commit)
- - [Squashing commits](../../workflow/gitlab_flow.md#squashing-commits-with-rebase)
+ - [Squashing commits](../gitlab_flow.md#squashing-commits-with-rebase)
### Concepts
diff --git a/doc/topics/git/migrate_to_git_lfs/index.md b/doc/topics/git/migrate_to_git_lfs/index.md
index 0c30b45c552..eec1c3c10c1 100644
--- a/doc/topics/git/migrate_to_git_lfs/index.md
+++ b/doc/topics/git/migrate_to_git_lfs/index.md
@@ -163,9 +163,9 @@ but commented out to help encourage others to add to it in the future. -->
## References
- [Getting Started with Git LFS](https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/)
-- [Migrate from Git Annex to Git LFS](../../../workflow/lfs/migrate_from_git_annex_to_git_lfs.md)
-- [GitLab's Git LFS user documentation](../../../workflow/lfs/manage_large_binaries_with_git_lfs.md)
-- [GitLab's Git LFS administrator documentation](../../../workflow/lfs/lfs_administration.md)
+- [Migrate from Git Annex to Git LFS](../../../administration/lfs/migrate_from_git_annex_to_git_lfs.md)
+- [GitLab's Git LFS user documentation](../../../administration/lfs/manage_large_binaries_with_git_lfs.md)
+- [GitLab's Git LFS administrator documentation](../../../administration/lfs/lfs_administration.md)
- Alternative method to [migrate an existing repo to Git LFS](https://github.com/git-lfs/git-lfs/wiki/Tutorial#migrating-existing-repository-data-to-lfs)
<!--
diff --git a/doc/topics/gitlab_flow.md b/doc/topics/gitlab_flow.md
new file mode 100644
index 00000000000..0fab4de8454
--- /dev/null
+++ b/doc/topics/gitlab_flow.md
@@ -0,0 +1,330 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/gitlab_flow.html'
+---
+
+# Introduction to GitLab Flow
+
+![GitLab Flow](img/gitlab_flow.png)
+
+Git allows a wide variety of branching strategies and workflows.
+Because of this, many organizations end up with workflows that are too complicated, not clearly defined, or not integrated with issue tracking systems.
+Therefore, we propose GitLab flow as a clearly defined set of best practices.
+It combines [feature-driven development](https://en.wikipedia.org/wiki/Feature-driven_development) and [feature branches](https://martinfowler.com/bliki/FeatureBranch.html) with issue tracking.
+
+Organizations coming to Git from other version control systems frequently find it hard to develop a productive workflow.
+This article describes GitLab flow, which integrates the Git workflow with an issue tracking system.
+It offers a simple, transparent, and effective way to work with Git.
+
+![Four stages (working copy, index, local repo, remote repo) and three steps between them](img/gitlab_flow_four_stages.png)
+
+When converting to Git, you have to get used to the fact that it takes three steps to share a commit with colleagues.
+Most version control systems have only one step: committing from the working copy to a shared server.
+In Git, you add files from the working copy to the staging area. After that, you commit them to your local repo.
+The third step is pushing to a shared remote repository.
+After getting used to these three steps, the next challenge is the branching model.
+
+![Multiple long-running branches and merging in all directions](img/gitlab_flow_messy_flow.png)
+
+Since many organizations new to Git have no conventions for how to work with it, their repositories can quickly become messy.
+The biggest problem is that many long-running branches emerge that all contain part of the changes.
+People have a hard time figuring out which branch has the latest code, or which branch to deploy to production.
+Frequently, the reaction to this problem is to adopt a standardized pattern such as [Git flow](https://nvie.com/posts/a-successful-git-branching-model/) and [GitHub flow](http://scottchacon.com/2011/08/31/github-flow.html).
+We think there is still room for improvement. In this document, we describe a set of practices we call GitLab flow.
+
+For a video introduction of how this works in GitLab, see [GitLab Flow](https://youtu.be/InKNIvky2KE).
+
+## Git flow and its problems
+
+![Git Flow timeline by Vincent Driessen, used with permission](img/gitlab_flow_gitdashflow.png)
+
+Git flow was one of the first proposals to use Git branches, and it has received a lot of attention.
+It suggests a `master` branch and a separate `develop` branch, as well as supporting branches for features, releases, and hotfixes.
+The development happens on the `develop` branch, moves to a release branch, and is finally merged into the `master` branch.
+
+Git flow is a well-defined standard, but its complexity introduces two problems.
+The first problem is that developers must use the `develop` branch and not `master`. `master` is reserved for code that is released to production.
+It is a convention to call your default branch `master` and to mostly branch from and merge to this.
+Since most tools automatically use the `master` branch as the default, it is annoying to have to switch to another branch.
+
+The second problem of Git flow is the complexity introduced by the hotfix and release branches.
+These branches can be a good idea for some organizations but are overkill for the vast majority of them.
+Nowadays, most organizations practice continuous delivery, which means that your default branch can be deployed.
+Continuous delivery removes the need for hotfix and release branches, including all the ceremony they introduce.
+An example of this ceremony is the merging back of release branches.
+Though specialized tools do exist to solve this, they require documentation and add complexity.
+Frequently, developers make mistakes such as merging changes only into `master` and not into the `develop` branch.
+The reason for these errors is that Git flow is too complicated for most use cases.
+For example, many projects do releases but don't need to do hotfixes.
+
+## GitHub flow as a simpler alternative
+
+![Master branch with feature branches merged in](img/gitlab_flow_github_flow.png)
+
+In reaction to Git flow, GitHub created a simpler alternative.
+[GitHub flow](https://guides.github.com/introduction/flow/index.html) has only feature branches and a `master` branch.
+This flow is clean and straightforward, and many organizations have adopted it with great success.
+Atlassian recommends [a similar strategy](https://www.atlassian.com/blog/git/simple-git-workflow-is-simple), although they rebase feature branches.
+Merging everything into the `master` branch and frequently deploying means you minimize the amount of unreleased code, which is in line with lean and continuous delivery best practices.
+However, this flow still leaves a lot of questions unanswered regarding deployments, environments, releases, and integrations with issues.
+With GitLab flow, we offer additional guidance for these questions.
+
+## Production branch with GitLab flow
+
+![Master branch and production branch with an arrow that indicates a deployment](img/gitlab_flow_production_branch.png)
+
+GitHub flow assumes you can deploy to production every time you merge a feature branch.
+While this is possible in some cases, such as SaaS applications, there are many cases where this is not possible.
+One case is where you don't control the timing of a release, for example, an iOS application that is released when it passes App Store validation.
+Another case is when you have deployment windows &mdash; for example, workdays from 10&nbsp;AM to 4&nbsp;PM when the operations team is at full capacity &mdash; but you also merge code at other times.
+In these cases, you can make a production branch that reflects the deployed code.
+You can deploy a new version by merging `master` into the production branch.
+If you need to know what code is in production, you can just checkout the production branch to see.
+The approximate time of deployment is easily visible as the merge commit in the version control system.
+This time is pretty accurate if you automatically deploy your production branch.
+If you need a more exact time, you can have your deployment script create a tag on each deployment.
+This flow prevents the overhead of releasing, tagging, and merging that happens with Git flow.
+
+## Environment branches with GitLab flow
+
+![Multiple branches with the code cascading from one to another](img/gitlab_flow_environment_branches.png)
+
+It might be a good idea to have an environment that is automatically updated to the `master` branch.
+Only, in this case, the name of this environment might differ from the branch name.
+Suppose you have a staging environment, a pre-production environment, and a production environment.
+In this case, deploy the `master` branch to staging.
+To deploy to pre-production, create a merge request from the `master` branch to the pre-production branch.
+Go live by merging the pre-production branch into the production branch.
+This workflow, where commits only flow downstream, ensures that everything is tested in all environments.
+If you need to cherry-pick a commit with a hotfix, it is common to develop it on a feature branch and merge it into `master` with a merge request.
+In this case, do not delete the feature branch yet.
+If `master` passes automatic testing, you then merge the feature branch into the other branches.
+If this is not possible because more manual testing is required, you can send merge requests from the feature branch to the downstream branches.
+
+## Release branches with GitLab flow
+
+![Master and multiple release branches that vary in length with cherry-picks from master](img/gitlab_flow_release_branches.png)
+
+You only need to work with release branches if you need to release software to the outside world.
+In this case, each branch contains a minor version, for example, 2-3-stable, 2-4-stable, etc.
+Create stable branches using `master` as a starting point, and branch as late as possible.
+By doing this, you minimize the length of time during which you have to apply bug fixes to multiple branches.
+After announcing a release branch, only add serious bug fixes to the branch.
+If possible, first merge these bug fixes into `master`, and then cherry-pick them into the release branch.
+If you start by merging into the release branch, you might forget to cherry-pick them into `master`, and then you'd encounter the same bug in subsequent releases.
+Merging into `master` and then cherry-picking into release is called an "upstream first" policy, which is also practiced by [Google](https://www.chromium.org/chromium-os/chromiumos-design-docs/upstream-first) and [Red Hat](https://www.redhat.com/en/blog/a-community-for-using-openstack-with-red-hat-rdo).
+Every time you include a bug fix in a release branch, increase the patch version (to comply with [Semantic Versioning](https://semver.org/)) by setting a new tag.
+Some projects also have a stable branch that points to the same commit as the latest released branch.
+In this flow, it is not common to have a production branch (or Git flow `master` branch).
+
+## Merge/pull requests with GitLab flow
+
+![Merge request with inline comments](img/gitlab_flow_mr_inline_comments.png)
+
+Merge or pull requests are created in a Git management application. They ask an assigned person to merge two branches.
+Tools such as GitHub and Bitbucket choose the name "pull request" since the first manual action is to pull the feature branch.
+Tools such as GitLab and others choose the name "merge request" since the final action is to merge the feature branch.
+In this article, we'll refer to them as merge requests.
+
+If you work on a feature branch for more than a few hours, it is good to share the intermediate result with the rest of the team.
+To do this, create a merge request without assigning it to anyone.
+Instead, mention people in the description or a comment, for example, "/cc @mark @susan."
+This indicates that the merge request is not ready to be merged yet, but feedback is welcome.
+Your team members can comment on the merge request in general or on specific lines with line comments.
+The merge request serves as a code review tool, and no separate code review tools should be needed.
+If the review reveals shortcomings, anyone can commit and push a fix.
+Usually, the person to do this is the creator of the merge request.
+The diff in the merge request automatically updates when new commits are pushed to the branch.
+
+When you are ready for your feature branch to be merged, assign the merge request to the person who knows most about the codebase you are changing.
+Also, mention any other people from whom you would like feedback.
+After the assigned person feels comfortable with the result, they can merge the branch.
+If the assigned person does not feel comfortable, they can request more changes or close the merge request without merging.
+
+In GitLab, it is common to protect the long-lived branches, e.g., the `master` branch, so that [most developers can't modify them](../user/permissions.md).
+So, if you want to merge into a protected branch, assign your merge request to someone with maintainer permissions.
+
+After you merge a feature branch, you should remove it from the source control software.
+In GitLab, you can do this when merging.
+Removing finished branches ensures that the list of branches shows only work in progress.
+It also ensures that if someone reopens the issue, they can use the same branch name without causing problems.
+
+NOTE: **Note:**
+When you reopen an issue you need to create a new merge request.
+
+![Remove checkbox for branch in merge requests](img/gitlab_flow_remove_checkbox.png)
+
+## Issue tracking with GitLab flow
+
+![Merge request with the branch name "15-require-a-password-to-change-it" and assignee field shown](img/gitlab_flow_merge_request.png)
+
+GitLab flow is a way to make the relation between the code and the issue tracker more transparent.
+
+Any significant change to the code should start with an issue that describes the goal.
+Having a reason for every code change helps to inform the rest of the team and to keep the scope of a feature branch small.
+In GitLab, each change to the codebase starts with an issue in the issue tracking system.
+If there is no issue yet, create the issue, as long as the change will take a significant amount of work, i.e., more than 1 hour.
+In many organizations, raising an issue is part of the development process because they are used in sprint planning.
+The issue title should describe the desired state of the system.
+For example, the issue title "As an administrator, I want to remove users without receiving an error" is better than "Admin can't remove users."
+
+When you are ready to code, create a branch for the issue from the `master` branch.
+This branch is the place for any work related to this change.
+
+NOTE: **Note:**
+The name of a branch might be dictated by organizational standards.
+
+When you are done or want to discuss the code, open a merge request.
+A merge request is an online place to discuss the change and review the code.
+
+If you open the merge request but do not assign it to anyone, it is a "Work In Progress" merge request.
+These are used to discuss the proposed implementation but are not ready for inclusion in the `master` branch yet.
+Start the title of the merge request with `[WIP]` or `WIP:` to prevent it from being merged before it's ready.
+
+When you think the code is ready, assign the merge request to a reviewer.
+The reviewer can merge the changes when they think the code is ready for inclusion in the `master` branch.
+When they press the merge button, GitLab merges the code and creates a merge commit that makes this event easily visible later on.
+Merge requests always create a merge commit, even when the branch could be merged without one.
+This merge strategy is called "no fast-forward" in Git.
+After the merge, delete the feature branch since it is no longer needed.
+In GitLab, this deletion is an option when merging.
+
+Suppose that a branch is merged but a problem occurs and the issue is reopened.
+In this case, it is no problem to reuse the same branch name since the first branch was deleted when it was merged.
+At any time, there is at most one branch for every issue.
+It is possible that one feature branch solves more than one issue.
+
+## Linking and closing issues from merge requests
+
+![Merge request showing the linked issues that will be closed](img/gitlab_flow_close_issue_mr.png)
+
+Link to issues by mentioning them in commit messages or the description of a merge request, for example, "Fixes #16" or "Duck typing is preferred. See #12."
+GitLab then creates links to the mentioned issues and creates comments in the issues linking back to the merge request.
+
+To automatically close linked issues, mention them with the words "fixes" or "closes," for example, "fixes #14" or "closes #67." GitLab closes these issues when the code is merged into the default branch.
+
+If you have an issue that spans across multiple repositories, create an issue for each repository and link all issues to a parent issue.
+
+## Squashing commits with rebase
+
+![Vim screen showing the rebase view](img/gitlab_flow_rebase.png)
+
+With Git, you can use an interactive rebase (`rebase -i`) to squash multiple commits into one or reorder them.
+This functionality is useful if you want to replace a couple of small commits with a single commit, or if you want to make the order more logical.
+
+However, you should never rebase commits you have pushed to a remote server.
+Rebasing creates new commits for all your changes, which can cause confusion because the same change would have multiple identifiers.
+It also causes merge errors for anyone working on the same branch because their history would not match with yours.
+Also, if someone has already reviewed your code, rebasing makes it hard to tell what changed since the last review.
+
+You should also never rebase commits authored by other people.
+Not only does this rewrite history, but it also loses authorship information.
+Rebasing prevents the other authors from being attributed and sharing part of the [`git blame`](https://git-scm.com/docs/git-blame).
+
+If a merge involves many commits, it may seem more difficult to undo.
+You might think to solve this by squashing all the changes into one commit before merging, but as discussed earlier, it is a bad idea to rebase commits that you have already pushed.
+Fortunately, there is an easy way to undo a merge with all its commits.
+The way to do this is by reverting the merge commit.
+Preserving this ability to revert a merge is a good reason to always use the "no fast-forward" (`--no-ff`) strategy when you merge manually.
+
+NOTE: **Note:**
+If you revert a merge commit and then change your mind, revert the revert commit to redo the merge.
+Git does not allow you to merge the code again otherwise.
+
+## Reducing merge commits in feature branches
+
+![List of sequential merge commits](img/gitlab_flow_merge_commits.png)
+
+Having lots of merge commits can make your repository history messy.
+Therefore, you should try to avoid merge commits in feature branches.
+Often, people avoid merge commits by just using rebase to reorder their commits after the commits on the `master` branch.
+Using rebase prevents a merge commit when merging `master` into your feature branch, and it creates a neat linear history.
+However, as discussed in [the section about rebasing](#squashing-commits-with-rebase), you should never rebase commits you have pushed to a remote server.
+This restriction makes it impossible to rebase work in progress that you already shared with your team, which is something we recommend.
+
+Rebasing also creates more work, since every time you rebase, you have to resolve similar conflicts.
+Sometimes you can reuse recorded resolutions (`rerere`), but merging is better since you only have to resolve conflicts once.
+Atlassian has a more thorough explanation of the tradeoffs between merging and rebasing [on their blog](https://www.atlassian.com/blog/git/git-team-workflows-merge-or-rebase).
+
+A good way to prevent creating many merge commits is to not frequently merge `master` into the feature branch.
+There are three reasons to merge in `master`: utilizing new code, resolving merge conflicts, and updating long-running branches.
+
+If you need to utilize some code that was introduced in `master` after you created the feature branch, you can often solve this by just cherry-picking a commit.
+
+If your feature branch has a merge conflict, creating a merge commit is a standard way of solving this.
+
+NOTE: **Note:**
+Sometimes you can use .gitattributes to reduce merge conflicts.
+For example, you can set your changelog file to use the [union merge driver](https://git-scm.com/docs/gitattributes#gitattributes-union) so that multiple new entries don't conflict with each other.
+
+The last reason for creating merge commits is to keep long-running feature branches up-to-date with the latest state of the project.
+The solution here is to keep your feature branches short-lived.
+Most feature branches should take less than one day of work.
+If your feature branches often take more than a day of work, try to split your features into smaller units of work.
+
+If you need to keep a feature branch open for more than a day, there are a few strategies to keep it up-to-date.
+One option is to use continuous integration (CI) to merge in `master` at the start of the day.
+Another option is to only merge in from well-defined points in time, for example, a tagged release.
+You could also use [feature toggles](https://martinfowler.com/bliki/FeatureToggle.html) to hide incomplete features so you can still merge back into `master` every day.
+
+> **Note:** Don't confuse automatic branch testing with continuous integration.
+> Martin Fowler makes this distinction in [his article about feature branches](https://martinfowler.com/bliki/FeatureBranch.html):
+>
+> "I've heard people say they are doing CI because they are running builds, perhaps using a CI server, on every branch with every commit.
+> That's continuous building, and a Good Thing, but there's no *integration*, so it's not CI."
+
+In conclusion, you should try to prevent merge commits, but not eliminate them.
+Your codebase should be clean, but your history should represent what actually happened.
+Developing software happens in small, messy steps, and it is OK to have your history reflect this.
+You can use tools to view the network graphs of commits and understand the messy history that created your code.
+If you rebase code, the history is incorrect, and there is no way for tools to remedy this because they can't deal with changing commit identifiers.
+
+## Commit often and push frequently
+
+Another way to make your development work easier is to commit often.
+Every time you have a working set of tests and code, you should make a commit.
+Splitting up work into individual commits provides context for developers looking at your code later.
+Smaller commits make it clear how a feature was developed, and they make it easy to roll back to a specific good point in time or to revert one code change without reverting several unrelated changes.
+
+Committing often also makes it easy to share your work, which is important so that everyone is aware of what you are working on.
+You should push your feature branch frequently, even when it is not yet ready for review.
+By sharing your work in a feature branch or [a merge request](#mergepull-requests-with-gitlab-flow), you prevent your team members from duplicating work.
+Sharing your work before it's complete also allows for discussion and feedback about the changes, which can help improve the code before it gets to review.
+
+## How to write a good commit message
+
+![Good and bad commit message](img/gitlab_flow_good_commit.png)
+
+A commit message should reflect your intention, not just the contents of the commit.
+It is easy to see the changes in a commit, so the commit message should explain why you made those changes.
+An example of a good commit message is: "Combine templates to reduce duplicate code in the user views."
+The words "change," "improve," "fix," and "refactor" don't add much information to a commit message.
+For example, "Improve XML generation" could be better written as "Properly escape special characters in XML generation."
+For more information about formatting commit messages, please see this excellent [blog post by Tim Pope](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
+
+## Testing before merging
+
+![Merge requests showing the test states: red, yellow, and green](img/gitlab_flow_ci_mr.png)
+
+In old workflows, the continuous integration (CI) server commonly ran tests on the `master` branch only.
+Developers had to ensure their code did not break the `master` branch.
+When using GitLab flow, developers create their branches from this `master` branch, so it is essential that it never breaks.
+Therefore, each merge request must be tested before it is accepted.
+CI software like Travis CI and GitLab CI show the build results right in the merge request itself to make this easy.
+
+There is one drawback to testing merge requests: the CI server only tests the feature branch itself, not the merged result.
+Ideally, the server could also test the `master` branch after each change.
+However, retesting on every commit to `master` is computationally expensive and means you are more frequently waiting for test results.
+Since feature branches should be short-lived, testing just the branch is an acceptable risk.
+If new commits in `master` cause merge conflicts with the feature branch, merge `master` back into the branch to make the CI server re-run the tests.
+As said before, if you often have feature branches that last for more than a few days, you should make your issues smaller.
+
+## Working with feature branches
+
+![Shell output showing git pull output](img/gitlab_flow_git_pull.png)
+
+When creating a feature branch, always branch from an up-to-date `master`.
+If you know before you start that your work depends on another branch, you can also branch from there.
+If you need to merge in another branch after starting, explain the reason in the merge commit.
+If you have not pushed your commits to a shared location yet, you can also incorporate changes by rebasing on `master` or another feature branch.
+Do not merge from upstream again if your code can work and merge cleanly without doing so.
+Merging only when needed prevents creating merge commits in your feature branch that later end up littering the `master` history.
diff --git a/doc/workflow/img/gitlab_flow.png b/doc/topics/img/gitlab_flow.png
index a6f3c947843..a6f3c947843 100644
--- a/doc/workflow/img/gitlab_flow.png
+++ b/doc/topics/img/gitlab_flow.png
Binary files differ
diff --git a/doc/workflow/img/ci_mr.png b/doc/topics/img/gitlab_flow_ci_mr.png
index 85a609cb814..85a609cb814 100644
--- a/doc/workflow/img/ci_mr.png
+++ b/doc/topics/img/gitlab_flow_ci_mr.png
Binary files differ
diff --git a/doc/workflow/img/close_issue_mr.png b/doc/topics/img/gitlab_flow_close_issue_mr.png
index 70de2fb6cee..70de2fb6cee 100644
--- a/doc/workflow/img/close_issue_mr.png
+++ b/doc/topics/img/gitlab_flow_close_issue_mr.png
Binary files differ
diff --git a/doc/workflow/img/environment_branches.png b/doc/topics/img/gitlab_flow_environment_branches.png
index 0aff33c6bb8..0aff33c6bb8 100644
--- a/doc/workflow/img/environment_branches.png
+++ b/doc/topics/img/gitlab_flow_environment_branches.png
Binary files differ
diff --git a/doc/workflow/img/four_stages.png b/doc/topics/img/gitlab_flow_four_stages.png
index 3ef6a33d2d4..3ef6a33d2d4 100644
--- a/doc/workflow/img/four_stages.png
+++ b/doc/topics/img/gitlab_flow_four_stages.png
Binary files differ
diff --git a/doc/workflow/img/git_pull.png b/doc/topics/img/gitlab_flow_git_pull.png
index 0e56e59471c..0e56e59471c 100644
--- a/doc/workflow/img/git_pull.png
+++ b/doc/topics/img/gitlab_flow_git_pull.png
Binary files differ
diff --git a/doc/workflow/img/gitdashflow.png b/doc/topics/img/gitlab_flow_gitdashflow.png
index 65900853d84..65900853d84 100644
--- a/doc/workflow/img/gitdashflow.png
+++ b/doc/topics/img/gitlab_flow_gitdashflow.png
Binary files differ
diff --git a/doc/workflow/img/github_flow.png b/doc/topics/img/gitlab_flow_github_flow.png
index 21a22becdb6..21a22becdb6 100644
--- a/doc/workflow/img/github_flow.png
+++ b/doc/topics/img/gitlab_flow_github_flow.png
Binary files differ
diff --git a/doc/workflow/img/good_commit.png b/doc/topics/img/gitlab_flow_good_commit.png
index ceb0d4b1691..ceb0d4b1691 100644
--- a/doc/workflow/img/good_commit.png
+++ b/doc/topics/img/gitlab_flow_good_commit.png
Binary files differ
diff --git a/doc/workflow/img/merge_commits.png b/doc/topics/img/gitlab_flow_merge_commits.png
index 4a80811c6e3..4a80811c6e3 100644
--- a/doc/workflow/img/merge_commits.png
+++ b/doc/topics/img/gitlab_flow_merge_commits.png
Binary files differ
diff --git a/doc/workflow/img/merge_request.png b/doc/topics/img/gitlab_flow_merge_request.png
index 010e95983fc..010e95983fc 100644
--- a/doc/workflow/img/merge_request.png
+++ b/doc/topics/img/gitlab_flow_merge_request.png
Binary files differ
diff --git a/doc/workflow/img/messy_flow.png b/doc/topics/img/gitlab_flow_messy_flow.png
index 4fa22d2bb5d..4fa22d2bb5d 100644
--- a/doc/workflow/img/messy_flow.png
+++ b/doc/topics/img/gitlab_flow_messy_flow.png
Binary files differ
diff --git a/doc/workflow/img/mr_inline_comments.png b/doc/topics/img/gitlab_flow_mr_inline_comments.png
index a18801f56e4..a18801f56e4 100644
--- a/doc/workflow/img/mr_inline_comments.png
+++ b/doc/topics/img/gitlab_flow_mr_inline_comments.png
Binary files differ
diff --git a/doc/workflow/img/production_branch.png b/doc/topics/img/gitlab_flow_production_branch.png
index c132d51bfb6..c132d51bfb6 100644
--- a/doc/workflow/img/production_branch.png
+++ b/doc/topics/img/gitlab_flow_production_branch.png
Binary files differ
diff --git a/doc/workflow/img/rebase.png b/doc/topics/img/gitlab_flow_rebase.png
index fe865177ba8..fe865177ba8 100644
--- a/doc/workflow/img/rebase.png
+++ b/doc/topics/img/gitlab_flow_rebase.png
Binary files differ
diff --git a/doc/workflow/img/release_branches.png b/doc/topics/img/gitlab_flow_release_branches.png
index 0a7f61d0248..0a7f61d0248 100644
--- a/doc/workflow/img/release_branches.png
+++ b/doc/topics/img/gitlab_flow_release_branches.png
Binary files differ
diff --git a/doc/workflow/img/remove_checkbox.png b/doc/topics/img/gitlab_flow_remove_checkbox.png
index fb0e792b37b..fb0e792b37b 100644
--- a/doc/workflow/img/remove_checkbox.png
+++ b/doc/topics/img/gitlab_flow_remove_checkbox.png
Binary files differ
diff --git a/doc/topics/index.md b/doc/topics/index.md
index b51f24b02e4..71048ec5aa4 100644
--- a/doc/topics/index.md
+++ b/doc/topics/index.md
@@ -11,6 +11,7 @@ tutorials, technical overviews, blog posts) and videos.
- [Authentication](authentication/index.md)
- [Continuous Integration (GitLab CI)](../ci/README.md)
- [Git](git/index.md)
+- [GitLab Flow](gitlab_flow.md)
- [GitLab Installation](../install/README.md)
- [GitLab Pages](../user/project/pages/index.md)
diff --git a/doc/university/README.md b/doc/university/README.md
index 8f5a5038bb9..9725cb14fc5 100644
--- a/doc/university/README.md
+++ b/doc/university/README.md
@@ -129,7 +129,7 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
1. [GitLab Flow vs Forking in GitLab - Video](https://www.youtube.com/watch?v=UGotqAUACZA)
1. [GitLab Flow Overview](https://about.gitlab.com/blog/2014/09/29/gitlab-flow/)
1. [Always Start with an Issue](https://about.gitlab.com/blog/2016/03/03/start-with-an-issue/)
-1. [GitLab Flow Documentation](../workflow/gitlab_flow.md)
+1. [GitLab Flow Documentation](../topics/gitlab_flow.md)
### 2.5. GitLab Comparisons
diff --git a/doc/university/training/gitlab_flow.md b/doc/university/training/gitlab_flow.md
index 66e645a0af8..b80eb031aee 100644
--- a/doc/university/training/gitlab_flow.md
+++ b/doc/university/training/gitlab_flow.md
@@ -38,7 +38,7 @@ type: reference
## More details
-For more information, read through the [GitLab Flow](../../workflow/gitlab_flow.md)
+For more information, read through the [GitLab Flow](../../topics/gitlab_flow.md)
documentation.
<!-- ## Troubleshooting
diff --git a/doc/user/admin_area/settings/account_and_limit_settings.md b/doc/user/admin_area/settings/account_and_limit_settings.md
index a1beee404eb..e443127a8a0 100644
--- a/doc/user/admin_area/settings/account_and_limit_settings.md
+++ b/doc/user/admin_area/settings/account_and_limit_settings.md
@@ -32,7 +32,7 @@ For instance, consider the following workflow:
1. Your team develops apps which require large files to be stored in
the application repository.
-1. Although you have enabled [Git LFS](../../../workflow/lfs/manage_large_binaries_with_git_lfs.md#git-lfs)
+1. Although you have enabled [Git LFS](../../../administration/lfs/manage_large_binaries_with_git_lfs.md#git-lfs)
to your project, your storage has grown significantly.
1. Before you exceed available storage, you set up a limit of 10 GB
per repository.
diff --git a/doc/user/admin_area/settings/usage_statistics.md b/doc/user/admin_area/settings/usage_statistics.md
index 98126f72a78..81edd9eac34 100644
--- a/doc/user/admin_area/settings/usage_statistics.md
+++ b/doc/user/admin_area/settings/usage_statistics.md
@@ -31,7 +31,7 @@ patches will need to be backported, making sure active GitLab instances remain
secure.
If you disable version check, this information will not be collected. Enable or
-disable the version check at **Admin area > Settings > Usage statistics**.
+disable the version check at **Admin area > Settings > Metrics and profiling > Usage statistics**.
## Usage ping **(CORE ONLY)**
@@ -85,7 +85,7 @@ will be able to show [usage statistics](../../instance_statistics/index.md)
of your instance to your users.
This can be restricted to admins by selecting "Only admins" in the Instance
-Statistics visibility section under **Admin area > Settings > Usage statistics**.
+Statistics visibility section under **Admin area > Settings > Metrics and profiling > Usage statistics**.
<!-- ## Troubleshooting
diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md
index f718e31e8bd..73406fd5037 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -177,7 +177,7 @@ For more details, see [SSH key restrictions](../../../security/ssh_keys_restrict
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/3586) in GitLab 10.3.
-This option is enabled by default. By disabling it, both [pull and push mirroring](../../../workflow/repository_mirroring.md) will no longer
+This option is enabled by default. By disabling it, both [pull and push mirroring](../../project/repository/repository_mirroring.md) will no longer
work in every repository and can only be re-enabled by an admin on a per-project basis.
![Mirror settings](img/mirror_settings.png)
diff --git a/doc/user/analytics/cycle_analytics.md b/doc/user/analytics/cycle_analytics.md
index e17202645d3..d6e468f3575 100644
--- a/doc/user/analytics/cycle_analytics.md
+++ b/doc/user/analytics/cycle_analytics.md
@@ -176,7 +176,7 @@ Learn more about Cycle Analytics in the following resources:
[ce-5986]: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/5986
[ce-20975]: https://gitlab.com/gitlab-org/gitlab-foss/issues/20975
[environment]: ../../ci/yaml/README.md#environment
-[GitLab flow]: ../../workflow/gitlab_flow.md
+[GitLab flow]: ../../topics/gitlab_flow.md
[idea to production]: https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab
[permissions]: ../permissions.md
[yml]: ../../ci/yaml/README.md
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index 6f8cc04adf8..0a51325b25c 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -287,7 +287,7 @@ Once you wrote your comment, you can either:
## Notifications
-- [Receive notifications](../../../workflow/notifications.md) for epic events.
+- [Receive notifications](../../profile/notifications.md) for epic events.
<!-- ## Troubleshooting
diff --git a/doc/workflow/img/todos_add_todo_sidebar.png b/doc/user/img/todos_add_todo_sidebar.png
index aefec7a2d9c..aefec7a2d9c 100644
--- a/doc/workflow/img/todos_add_todo_sidebar.png
+++ b/doc/user/img/todos_add_todo_sidebar.png
Binary files differ
diff --git a/doc/workflow/img/todos_icon.png b/doc/user/img/todos_icon.png
index 9fee4337a75..9fee4337a75 100644
--- a/doc/workflow/img/todos_icon.png
+++ b/doc/user/img/todos_icon.png
Binary files differ
diff --git a/doc/workflow/img/todos_index.png b/doc/user/img/todos_index.png
index 99c1575d157..99c1575d157 100644
--- a/doc/workflow/img/todos_index.png
+++ b/doc/user/img/todos_index.png
Binary files differ
diff --git a/doc/workflow/img/todos_mark_done_sidebar.png b/doc/user/img/todos_mark_done_sidebar.png
index 2badd880b40..2badd880b40 100644
--- a/doc/workflow/img/todos_mark_done_sidebar.png
+++ b/doc/user/img/todos_mark_done_sidebar.png
Binary files differ
diff --git a/doc/workflow/img/todo_list_item.png b/doc/user/img/todos_todo_list_item.png
index 91bbf9e5373..91bbf9e5373 100644
--- a/doc/workflow/img/todo_list_item.png
+++ b/doc/user/img/todos_todo_list_item.png
Binary files differ
diff --git a/doc/user/index.md b/doc/user/index.md
index 37b99eb7413..0c6fb0aa5e2 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -58,7 +58,7 @@ With GitLab Enterprise Edition, you can also:
- Use [Burndown Charts](project/milestones/burndown_charts.md) to track progress during a sprint or while working on a new version of their software.
- Leverage [Elasticsearch](../integration/elasticsearch.md) with [Advanced Global Search](search/advanced_global_search.md) and [Advanced Syntax Search](search/advanced_search_syntax.md) for faster, more advanced code search across your entire GitLab instance.
- [Authenticate users with Kerberos](../integration/kerberos.md).
-- [Mirror a repository](../workflow/repository_mirroring.md) from elsewhere on your local server.
+- [Mirror a repository](project/repository/repository_mirroring.md) from elsewhere on your local server.
- [Export issues as CSV](project/issues/csv_export.md).
- View your entire CI/CD pipeline involving more than one project with [Multiple-Project Pipelines](../ci/multi_project_pipeline_graphs.md).
- [Lock files](project/file_lock.md) to prevent conflicts.
@@ -135,7 +135,7 @@ supported.
## Todos
-Never forget to reply to your collaborators. [GitLab Todos](../workflow/todos.md)
+Never forget to reply to your collaborators. [GitLab Todos](todos.md)
are a tool for working faster and more effectively with your team,
by listing all user or group mentions, as well as issues and merge
requests you're assigned to.
@@ -150,6 +150,11 @@ requests you're assigned to.
you have quick access to. You can also gather feedback on them through
[Discussions](#Discussions).
+## Keyboard shortcuts
+
+There are many [keyboard shortcuts](shortcuts.md) in GitLab to help you navigate between
+pages and accomplish tasks faster.
+
## Integrations
[Integrate GitLab](../integration/README.md) with your preferred tool,
diff --git a/doc/workflow/img/notification_global_settings.png b/doc/user/profile/img/notification_global_settings.png
index 699f726c442..699f726c442 100644
--- a/doc/workflow/img/notification_global_settings.png
+++ b/doc/user/profile/img/notification_global_settings.png
Binary files differ
diff --git a/doc/workflow/img/notification_group_settings.png b/doc/user/profile/img/notification_group_settings.png
index ed5e9459216..ed5e9459216 100644
--- a/doc/workflow/img/notification_group_settings.png
+++ b/doc/user/profile/img/notification_group_settings.png
Binary files differ
diff --git a/doc/workflow/img/notification_project_settings.png b/doc/user/profile/img/notification_project_settings.png
index e2db2037d94..e2db2037d94 100644
--- a/doc/workflow/img/notification_project_settings.png
+++ b/doc/user/profile/img/notification_project_settings.png
Binary files differ
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 9c4001f0a79..06e4eac6623 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -53,7 +53,7 @@ From there, you can:
[use GitLab as an OAuth provider](../../integration/oauth_provider.md#introduction-to-oauth)
- Manage [personal access tokens](personal_access_tokens.md) to access your account via API and authorized applications
- Add and delete emails linked to your account
-- Choose which email to use for notifications, web-based commits, and display on your public profile
+- Choose which email to use for [notifications](notifications.md), web-based commits, and display on your public profile
- Manage [SSH keys](../../ssh/README.md) to access your account via SSH
- Manage your [preferences](preferences.md#syntax-highlighting-theme)
to customize your own GitLab experience
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
new file mode 100644
index 00000000000..e75edc7f753
--- /dev/null
+++ b/doc/user/profile/notifications.md
@@ -0,0 +1,176 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/notifications.html'
+---
+
+# GitLab Notification Emails
+
+GitLab has a notification system in place to notify a user of events that are important for the workflow.
+
+## Notification settings
+
+You can find notification settings under the user profile.
+
+![notification settings](img/notification_global_settings.png)
+
+Notification settings are divided into three groups:
+
+- Global settings
+- Group settings
+- Project settings
+
+Each of these settings have levels of notification:
+
+- Global: For groups and projects, notifications as per global settings.
+- Watch: Receive notifications for any activity.
+- Participate: Receive notifications for threads you have participated in.
+- On Mention: Receive notifications when `@mentioned` in comments.
+- Disabled: Turns off notifications.
+- Custom: Receive notifications for custom selected events.
+
+> Introduced in GitLab 12.0
+
+You can also select an email address to receive notifications for each group you belong to.
+
+### Global Settings
+
+Global settings are at the bottom of the hierarchy.
+Any setting set here will be overridden by a setting at the group or a project level.
+
+Group or Project settings can use `global` notification setting which will then use
+anything that is set at Global Settings.
+
+### Group Settings
+
+![notification settings](img/notification_group_settings.png)
+
+Group settings are taking precedence over Global Settings but are on a level below Project or Subgroup settings:
+
+```
+Group < Subgroup < Project
+```
+
+This means that you can set a different level of notifications per group while still being able
+to have a finer level setting per project or subgroup.
+Organization like this is suitable for users that belong to different groups but don't have the
+same need for being notified for every group they are member of.
+These settings can be configured on group page under the name of the group. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown.
+
+The group owner can disable email notifications for a group, which includes
+its subgroups and projects. If this is the case, you will not receive any corresponding notifications,
+and the notification button will be disabled with an explanatory tooltip.
+
+### Project Settings
+
+![notification settings](img/notification_project_settings.png)
+
+Project settings are at the top level and any setting placed at this level will take precedence of any
+other setting.
+This is suitable for users that have different needs for notifications per project basis.
+These settings can be configured on project page under the name of the project. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown.
+
+The project owner (or its group owner) can disable email notifications for the project.
+If this is the case, you will not receive any corresponding notifications, and the notification
+button will be disabled with an explanatory tooltip.
+
+## Notification events
+
+Below is the table of events users can be notified of:
+
+| Event | Sent to | Settings level |
+|------------------------------|---------------------|------------------------------|
+| New SSH key added | User | Security email, always sent. |
+| New email added | User | Security email, always sent. |
+| Email changed | User | Security email, always sent. |
+| Password changed | User | Security email, always sent. |
+| New user created | User | Sent on user creation, except for OmniAuth (LDAP)|
+| User added to project | User | Sent when user is added to project |
+| Project access level changed | User | Sent when user project access level is changed |
+| User added to group | User | Sent when user is added to group |
+| Group access level changed | User | Sent when user group access level is changed |
+| Project moved | Project members (1) | (1) not disabled |
+| New release | Project members | Custom notification |
+
+### Issue / Epics / Merge request events
+
+In most of the below cases, the notification will be sent to:
+
+- Participants:
+ - the author and assignee of the issue/merge request
+ - authors of comments on the issue/merge request
+ - anyone mentioned by `@username` in the title or description of the issue, merge request or epic **(ULTIMATE)**
+ - anyone with notification level "Participating" or higher that is mentioned by `@username`
+ in any of the comments on the issue, merge request, or epic **(ULTIMATE)**
+- Watchers: users with notification level "Watch"
+- Subscribers: anyone who manually subscribed to the issue, merge request, or epic **(ULTIMATE)**
+- Custom: Users with notification level "custom" who turned on notifications for any of the events present in the table below
+
+| Event | Sent to |
+|------------------------|---------|
+| New issue | |
+| Close issue | |
+| Reassign issue | The above, plus the old assignee |
+| Reopen issue | |
+| Due issue | Participants and Custom notification level with this event selected |
+| Change milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected |
+| Remove milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected |
+| New merge request | |
+| Push to merge request | Participants and Custom notification level with this event selected |
+| Reassign merge request | The above, plus the old assignee |
+| Close merge request | |
+| Reopen merge request | |
+| Merge merge request | |
+| Change milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected |
+| Remove milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected |
+| New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher |
+| Failed pipeline | The author of the pipeline |
+| Successful pipeline | The author of the pipeline, if they have the custom notification setting for successful pipelines set |
+| New epic **(ULTIMATE)** | |
+| Close epic **(ULTIMATE)** | |
+| Reopen epic **(ULTIMATE)** | |
+
+In addition, if the title or description of an Issue or Merge Request is
+changed, notifications will be sent to any **new** mentions by `@username` as
+if they had been mentioned in the original text.
+
+You won't receive notifications for Issues, Merge Requests or Milestones created
+by yourself (except when an issue is due). You will only receive automatic
+notifications when somebody else comments or adds changes to the ones that
+you've created or mentions you.
+
+If an open merge request becomes unmergeable due to conflict, its author will be notified about the cause.
+If a user has also set the merge request to automatically merge once pipeline succeeds,
+then that user will also be notified.
+
+### Email Headers
+
+Notification emails include headers that provide extra content about the notification received:
+
+| Header | Description |
+|-----------------------------|-------------------------------------------------------------------------|
+| X-GitLab-Project | The name of the project the notification belongs to |
+| X-GitLab-Project-Id | The ID of the project |
+| X-GitLab-Project-Path | The path of the project |
+| X-GitLab-(Resource)-ID | The ID of the resource the notification is for, where resource is `Issue`, `MergeRequest`, `Commit`, etc|
+| X-GitLab-Discussion-ID | Only in comment emails, the ID of the thread the comment is from |
+| X-GitLab-Pipeline-Id | Only in pipeline emails, the ID of the pipeline the notification is for |
+| X-GitLab-Reply-Key | A unique token to support reply by email |
+| X-GitLab-NotificationReason | The reason for being notified. "mentioned", "assigned", etc |
+| List-Id | The path of the project in a RFC 2919 mailing list identifier useful for email organization, for example, with Gmail filters |
+
+#### X-GitLab-NotificationReason
+
+This header holds the reason for the notification to have been sent out,
+where reason can be `mentioned`, `assigned`, `own_activity`, etc.
+Only one reason is sent out according to its priority:
+
+- `own_activity`
+- `assigned`
+- `mentioned`
+
+The reason in this header will also be shown in the footer of the notification email. For example an email with the
+reason `assigned` will have this sentence in the footer:
+`"You are receiving this email because you have been assigned an item on {configured GitLab hostname}"`
+
+NOTE: **Note:**
+Only reasons listed above have been implemented so far.
+Further implementation is [being discussed](https://gitlab.com/gitlab-org/gitlab/issues/20689).
diff --git a/doc/user/profile/preferences.md b/doc/user/profile/preferences.md
index 82a6d2b3703..9b43f6317d0 100644
--- a/doc/user/profile/preferences.md
+++ b/doc/user/profile/preferences.md
@@ -82,7 +82,7 @@ You have 8 options here that you can use for your default dashboard view:
- Your projects' activity
- Starred projects' activity
- Your groups
-- Your [Todos](../../workflow/todos.md)
+- Your [Todos](../todos.md)
- Assigned Issues
- Assigned Merge Requests
- Operations Dashboard **(PREMIUM)**
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index 9ecb785d6fe..26995809d84 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -205,9 +205,13 @@ To add an existing Kubernetes cluster to your project:
`default-token-xxxxx`. Copy that token name for use below.
- Get the certificate by running this command:
- ```sh
- kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
- ```
+ ```sh
+ kubectl get secret <secret name> -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
+ ```
+
+ NOTE: **Note:**
+ If the command returns the entire certificate chain, you need copy the *root ca*
+ certificate at the bottom of the chain.
- **Token** -
GitLab authenticates against Kubernetes using service tokens, which are
diff --git a/doc/workflow/time_tracking/img/time_tracking_example_v12_2.png b/doc/user/project/img/time_tracking_example_v12_2.png
index 31d8c490ed1..31d8c490ed1 100644
--- a/doc/workflow/time_tracking/img/time_tracking_example_v12_2.png
+++ b/doc/user/project/img/time_tracking_example_v12_2.png
Binary files differ
diff --git a/doc/workflow/time_tracking/img/time_tracking_sidebar_v8_16.png b/doc/user/project/img/time_tracking_sidebar_v8_16.png
index 22124afed6f..22124afed6f 100644
--- a/doc/workflow/time_tracking/img/time_tracking_sidebar_v8_16.png
+++ b/doc/user/project/img/time_tracking_sidebar_v8_16.png
Binary files differ
diff --git a/doc/user/project/import/github.md b/doc/user/project/import/github.md
index 0aeca7f73ad..9b98c52c4b8 100644
--- a/doc/user/project/import/github.md
+++ b/doc/user/project/import/github.md
@@ -125,7 +125,7 @@ your GitHub repositories are listed.
## Mirroring and pipeline status sharing
-Depending your GitLab tier, [project mirroring](../../../workflow/repository_mirroring.md) can be set up to keep
+Depending your GitLab tier, [project mirroring](../repository/repository_mirroring.md) can be set up to keep
your imported project in sync with its GitHub copy.
Additionally, you can configure GitLab to send pipeline status updates back GitHub with the
diff --git a/doc/user/project/index.md b/doc/user/project/index.md
index 7ae288996da..c173d3d3e11 100644
--- a/doc/user/project/index.md
+++ b/doc/user/project/index.md
@@ -26,6 +26,7 @@ When you create a project in GitLab, you'll have access to a large number of
from messing with history or pushing code without review
- [Protected tags](protected_tags.md): Control over who has
permission to create tags, and prevent accidental update or deletion
+ - [Repository mirroring](repository/repository_mirroring.md)
- [Signing commits](gpg_signed_commits/index.md): use GPG to sign your commits
- [Deploy tokens](deploy_tokens/index.md): Manage project-based deploy tokens that allow permanent access to the repository and Container Registry.
- [Web IDE](web_ide/index.md)
@@ -44,7 +45,7 @@ When you create a project in GitLab, you'll have access to a large number of
- [Review Apps](../../ci/review_apps/index.md): Live preview the results
of the changes proposed in a merge request in a per-branch basis
- [Labels](labels.md): Organize issues and merge requests by labels
-- [Time Tracking](../../workflow/time_tracking.md): Track estimate time
+- [Time Tracking](time_tracking.md): Track estimate time
and time spent on
the conclusion of an issue or merge request
- [Milestones](milestones/index.md): Work towards a target date
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index d7666d00e76..cca1612dfef 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -355,6 +355,8 @@ Once enabled, an issue will be opened automatically when an alert is triggered w
- Optional list of attached annotations extracted from `annotations/*`
- Alert [GFM](../../markdown.md): GitLab Flavored Markdown from `annotations/gitlab_incident_markdown`
+When GitLab recieves a **Recovery Alert**, it will automatically close the associated issue. This action will be recorded as a system message on the issue indicated that it was closed automatically by the GitLab Alert bot.
+
To further customize the issue, you can add labels, mentions, or any other supported [quick action](../quick_actions.md) in the selected issue template, which will apply to all incidents. To limit quick actions or other information to only specific types of alerts, use the `annotations/gitlab_incident_markdown` field.
Since [version 12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/63373), GitLab will tag each incident issue with the `incident` label automatically. If the label does not yet exist, it will be created automatically as well.
diff --git a/doc/user/project/issues/csv_export.md b/doc/user/project/issues/csv_export.md
index fb7fdde7b94..b97bcd47f61 100644
--- a/doc/user/project/issues/csv_export.md
+++ b/doc/user/project/issues/csv_export.md
@@ -67,8 +67,8 @@ Data will be encoded with a comma as the column delimiter, with `"` used to quot
| Milestone | Title of the issue milestone |
| Weight | Issue weight |
| Labels | Title of any labels joined with a `,` |
-| Time Estimate | [Time estimate](../../../workflow/time_tracking.md#estimates) in seconds |
-| Time Spent | [Time spent](../../../workflow/time_tracking.md#time-spent) in seconds |
+| Time Estimate | [Time estimate](../time_tracking.md#estimates) in seconds |
+| Time Spent | [Time spent](../time_tracking.md#time-spent) in seconds |
## Limitations
diff --git a/doc/user/project/issues/design_management.md b/doc/user/project/issues/design_management.md
index 169da7049a6..86c80e95699 100644
--- a/doc/user/project/issues/design_management.md
+++ b/doc/user/project/issues/design_management.md
@@ -38,8 +38,6 @@ to be enabled:
- Files uploaded must have a file extension of either `png`, `jpg`, `jpeg`, `gif`, `bmp`, `tiff` or `ico`.
The [`svg` extension is not yet supported](https://gitlab.com/gitlab-org/gitlab/issues/12771).
- Design uploads are limited to 10 files at a time.
-- Design Management is
- [not yet supported in the project export](https://gitlab.com/gitlab-org/gitlab/issues/11090).
- Design Management data
[isn't deleted when a project is destroyed](https://gitlab.com/gitlab-org/gitlab/issues/13429) yet.
- Design Management data [won't be moved](https://gitlab.com/gitlab-org/gitlab/issues/13426)
diff --git a/doc/user/project/issues/due_dates.md b/doc/user/project/issues/due_dates.md
index 240859651e2..b19d5dc1650 100644
--- a/doc/user/project/issues/due_dates.md
+++ b/doc/user/project/issues/due_dates.md
@@ -33,7 +33,7 @@ the icon and the date colored red. You can sort issues by those that are
![Issues with due dates in the issues index page](img/due_dates_issues_index_page.png)
-Due dates also appear in your [todos list](../../../workflow/todos.md).
+Due dates also appear in your [todos list](../../todos.md).
![Issues with due dates in the todos](img/due_dates_todos.png)
diff --git a/doc/workflow/issue_weight/issue.png b/doc/user/project/issues/img/issue_weight.png
index 3800b5940b8..3800b5940b8 100644
--- a/doc/workflow/issue_weight/issue.png
+++ b/doc/user/project/issues/img/issue_weight.png
Binary files differ
diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md
index 01f4eb5b912..f4e9434ef1a 100644
--- a/doc/user/project/issues/issue_data_and_actions.md
+++ b/doc/user/project/issues/issue_data_and_actions.md
@@ -41,7 +41,7 @@ after it is closed.
#### 2. To Do
-You can add issues to and remove issues from your [GitLab To-Do List](../../../workflow/todos.md).
+You can add issues to and remove issues from your [GitLab To-Do List](../../todos.md).
The button to do this has a different label depending on whether the issue is already on your To-Do List or not. If the issue is:
@@ -83,9 +83,9 @@ Select a [milestone](../milestones/index.md) to attribute that issue to.
#### 6. Time Tracking
-Use [GitLab Quick Actions](../quick_actions.md) to [track estimates and time spent on issues](../../../workflow/time_tracking.md).
-You can add an [estimate of the time it will take](../../../workflow/time_tracking.md#estimates)
-to resolve the issue, and also add [the time spent](../../../workflow/time_tracking.md#time-spent)
+Use [GitLab Quick Actions](../quick_actions.md) to [track estimates and time spent on issues](../time_tracking.md).
+You can add an [estimate of the time it will take](../time_tracking.md#estimates)
+to resolve the issue, and also add [the time spent](../time_tracking.md#time-spent)
on the resolution of the issue.
#### 7. Due date
@@ -109,7 +109,7 @@ from which you can select **Create new label**.
#### 9. Weight **(STARTER)**
-[Assign a weight](../../../workflow/issue_weight.md) to an issue.
+[Assign a weight](issue_weight.md) to an issue.
Larger values are used to indicate more effort is required to complete the issue. Only
positive values or zero are allowed.
@@ -131,7 +131,7 @@ or were mentioned in the description or threads.
#### 13. Notifications
-Click on the icon to enable/disable [notifications](../../../workflow/notifications.md#issue--epics--merge-request-events)
+Click on the icon to enable/disable [notifications](../../profile/notifications.md#issue--epics--merge-request-events)
for the issue. This will automatically enable if you participate in the issue in any way.
- **Enable**: If you are not a participant in the discussion on that issue, but
@@ -162,7 +162,7 @@ allowing many formatting options.
You can mention a user or a group present in your GitLab instance with `@username` or
`@groupname` and they will be notified via todos and email, unless they have disabled
all notifications in their profile settings. This is controlled in the
-[notification settings](../../../workflow/notifications.md).
+[notification settings](../../profile/notifications.md).
Mentions for yourself (the current logged in user), will be highlighted in a different
color, allowing you to easily see which comments involve you, helping you focus on
diff --git a/doc/user/project/issues/issue_weight.md b/doc/user/project/issues/issue_weight.md
new file mode 100644
index 00000000000..4b8d2318e9b
--- /dev/null
+++ b/doc/user/project/issues/issue_weight.md
@@ -0,0 +1,25 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/issue_weight.html'
+---
+
+# Issue weight **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/76) in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
+
+When you have a lot of issues, it can be hard to get an overview.
+By adding a weight to each issue, you can get a better idea of how much time,
+value or complexity a given issue has or will cost.
+
+You can set the weight of an issue during its creation, by simply changing the
+value in the dropdown menu. You can set it to a non-negative integer
+value from 0, 1, 2, and so on. (The database stores a 4-byte value, so the
+upper bound is essentially limitless).
+You can remove weight from an issue
+as well.
+
+This value will appear on the right sidebar of an individual issue, as well as
+in the issues page next to a distinctive balance scale icon.
+
+As an added bonus, you can see the total sum of all issues on the milestone page.
+
+![issue page](img/issue_weight.png)
diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md
index cfd6d4eaf4b..d8356abdd1c 100644
--- a/doc/user/project/labels.md
+++ b/doc/user/project/labels.md
@@ -210,8 +210,8 @@ The following can be filtered by labels:
## Subscribing to labels
From the project label list page and the group label list page, you can subscribe
-to [notifications](../../workflow/notifications.md) of a given label, to alert you
-that the label has been assigned to an epic, issue, and merge request.
+to [notifications](../profile/notifications.md) of a given label, to alert you
+that the label has been assigned to an epic, issue, or merge request.
![Labels subscriptions](img/labels_subscriptions_v12_1.png)
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index 00879aae931..97bd5dc3bc6 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -27,7 +27,7 @@ With GitLab merge requests, you can:
- Assign it to any registered user, and change the assignee how many times you need
- Assign a [milestone](../../project/milestones/index.md) and track the development of a broader implementation
- Organize your issues and merge requests consistently throughout the project with [labels](../../project/labels.md)
-- Add a time estimation and the time spent with that merge request with [Time Tracking](../../../workflow/time_tracking.md#time-tracking)
+- Add a time estimation and the time spent with that merge request with [Time Tracking](../time_tracking.md#time-tracking)
- [Resolve merge conflicts from the UI](#resolve-conflicts)
- Enable [fast-forward merge requests](#fast-forward-merge-requests)
- Enable [semi-linear history merge requests](#semi-linear-history-merge-requests) as another security layer to guarantee the pipeline is passing in the target branch
diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md
index 105854ccd33..03f524f5582 100644
--- a/doc/user/project/milestones/index.md
+++ b/doc/user/project/milestones/index.md
@@ -107,7 +107,7 @@ Not all features in the project milestone view are available in the group milest
| Feature | Project milestone view | Group milestone view |
|--------------------------------------|:----------------------:|:--------------------:|
-| Title an description | ✓ | ✓ |
+| Title and description | ✓ | ✓ |
| Issues assigned to milestone | ✓ | |
| Merge requests assigned to milestone | ✓ | |
| Participants and labels used | ✓ | |
diff --git a/doc/user/project/operations/error_tracking.md b/doc/user/project/operations/error_tracking.md
index f93c98f0218..50a67bddf01 100644
--- a/doc/user/project/operations/error_tracking.md
+++ b/doc/user/project/operations/error_tracking.md
@@ -41,5 +41,6 @@ NOTE: **Note:**
You will need at least Reporter [permissions](../../permissions.md) to view the Error Tracking list.
The Error Tracking list may be found at **Operations > Error Tracking** in your project's sidebar.
+Errors can be filtered by title.
![Error Tracking list](img/error_tracking_list.png)
diff --git a/doc/user/project/operations/img/error_tracking_list.png b/doc/user/project/operations/img/error_tracking_list.png
index 194c7b440a4..79b464e021e 100644
--- a/doc/user/project/operations/img/error_tracking_list.png
+++ b/doc/user/project/operations/img/error_tracking_list.png
Binary files differ
diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md
index b7c9faeb1df..0aea7f76b30 100644
--- a/doc/user/project/protected_branches.md
+++ b/doc/user/project/protected_branches.md
@@ -55,7 +55,7 @@ the actions that different roles can perform with the protected branch.
For example, you could set "Allowed to push" to "No one", and "Allowed to merge"
to "Developers + Maintainers", to require _everyone_ to submit a merge request for
changes going into the protected branch. This is compatible with workflows like
-the [GitLab workflow](../../workflow/gitlab_flow.md).
+the [GitLab workflow](../../topics/gitlab_flow.md).
However, there are workflows where that is not needed, and only protecting from
force pushes and branch removal is useful. For those workflows, you can allow
diff --git a/doc/workflow/releases/new_tag.png b/doc/user/project/releases/img/new_tag.png
index 6137ad2ee56..6137ad2ee56 100644
--- a/doc/workflow/releases/new_tag.png
+++ b/doc/user/project/releases/img/new_tag.png
Binary files differ
diff --git a/doc/workflow/releases/tags.png b/doc/user/project/releases/img/tags.png
index 4c032f96125..4c032f96125 100644
--- a/doc/workflow/releases/tags.png
+++ b/doc/user/project/releases/img/tags.png
Binary files differ
diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md
index ceb077ab8af..1ab348f57d4 100644
--- a/doc/user/project/releases/index.md
+++ b/doc/user/project/releases/index.md
@@ -77,6 +77,26 @@ following modal window will be then displayed, from which you can select **New r
![Custom notification - New release](img/custom_notifications_new_release_v12_4.png)
+## Add release notes to Git tags
+
+You can add release notes to any Git tag using the notes feature. Release notes
+behave like any other markdown form in GitLab so you can write text and
+drag and drop files to it. Release notes are stored in GitLab's database.
+
+There are several ways to add release notes:
+
+- In the interface, when you create a new Git tag
+- In the interface, by adding a note to an existing Git tag
+- Using the GitLab API
+
+### New tag page with release notes text area
+
+![new_tag](img/new_tag.png)
+
+### Tags page with button to add or edit release notes for existing Git tag
+
+![tags](img/tags.png)
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/user/project/repository/file_finder.md b/doc/user/project/repository/file_finder.md
new file mode 100644
index 00000000000..7732b76fc35
--- /dev/null
+++ b/doc/user/project/repository/file_finder.md
@@ -0,0 +1,45 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/file_finder.html'
+---
+
+# File finder
+
+> [Introduced][gh-9889] in GitLab 8.4.
+
+The file finder feature allows you to search for a file in a repository using the
+GitLab UI.
+
+You can find the **Find File** button when in the **Files** section of a
+project.
+
+![Find file button](img/file_finder_find_button.png)
+
+For those who prefer to keep their fingers on the keyboard, there is a
+[shortcut button](../../../workflow/shortcuts.md) as well, which you can invoke from _anywhere_
+in a project.
+
+Press `t` to launch the File search function when in **Issues**,
+**Merge requests**, **Milestones**, even the project's settings.
+
+Start typing what you are searching for and watch the magic happen. With the
+up/down arrows, you go up and down the results, with `Esc` you close the search
+and go back to **Files**.
+
+## How it works
+
+The File finder feature is powered by the [Fuzzy filter](https://github.com/jeancroy/fuzz-aldrin-plus) library.
+
+It implements a fuzzy search with highlight, and tries to provide intuitive
+results by recognizing patterns that people use while searching.
+
+For example, consider the [GitLab CE repository][ce] and that we want to open
+the `app/controllers/admin/deploy_keys_controller.rb` file.
+
+Using fuzzy search, we start by typing letters that get us closer to the file.
+
+**Protip:** To narrow down your search, include `/` in your search terms.
+
+![Find file button](img/file_finder_find_file.png)
+
+[gh-9889]: https://github.com/gitlabhq/gitlabhq/pull/9889 "File finder pull request"
+[ce]: https://gitlab.com/gitlab-org/gitlab-foss/tree/master "GitLab CE repository"
diff --git a/doc/user/project/repository/forking_workflow.md b/doc/user/project/repository/forking_workflow.md
new file mode 100644
index 00000000000..5d1d3894fec
--- /dev/null
+++ b/doc/user/project/repository/forking_workflow.md
@@ -0,0 +1,55 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/forking_workflow.html'
+---
+
+# Project forking workflow
+
+Forking a project to your own namespace is useful if you have no write
+access to the project you want to contribute to. If you do have write
+access or can request it, we recommend working together in the same
+repository since it is simpler. See our [GitLab Flow](../../../workflow/gitlab_flow.md)
+document more information about using branches to work together.
+
+## Creating a fork
+
+Forking a project is in most cases a two-step process.
+
+1. Click on the fork button located located in between the star and clone buttons on the project's home page.
+
+ ![Fork button](img/forking_workflow_fork_button.png)
+
+1. Once you do that, you'll be presented with a screen where you can choose
+ the namespace to fork to. Only namespaces (groups and your own
+ namespace) where you have write access to, will be shown. Click on the
+ namespace to create your fork there.
+
+ ![Choose namespace](img/forking_workflow_choose_namespace.png)
+
+ **Note:**
+ If the namespace you chose to fork the project to has another project with
+ the same path name, you will be presented with a warning that the forking
+ could not be completed. Try to resolve the error before repeating the forking
+ process.
+
+ ![Path taken error](img/forking_workflow_path_taken_error.png)
+
+After the forking is done, you can start working on the newly created
+repository. There, you will have full [Owner](../../permissions.md)
+access, so you can set it up as you please.
+
+## Merging upstream
+
+Once you are ready to send your code back to the main project, you need
+to create a merge request. Choose your forked project's main branch as
+the source and the original project's main branch as the destination and
+create the [merge request](../merge_requests/index.md).
+
+![Selecting branches](img/forking_workflow_branch_select.png)
+
+You can then assign the merge request to someone to have them review
+your changes. Upon pressing the 'Submit Merge Request' button, your
+changes will be added to the repository and branch you're merging into.
+
+![New merge request](img/forking_workflow_merge_request.png)
+
+[gitlab flow]: https://about.gitlab.com/blog/2014/09/29/gitlab-flow/ "GitLab Flow blog post"
diff --git a/doc/workflow/img/file_finder_find_button.png b/doc/user/project/repository/img/file_finder_find_button.png
index 0c2d7d7bc73..0c2d7d7bc73 100644
--- a/doc/workflow/img/file_finder_find_button.png
+++ b/doc/user/project/repository/img/file_finder_find_button.png
Binary files differ
diff --git a/doc/workflow/img/file_finder_find_file.png b/doc/user/project/repository/img/file_finder_find_file.png
index c2212c7cd9e..c2212c7cd9e 100644
--- a/doc/workflow/img/file_finder_find_file.png
+++ b/doc/user/project/repository/img/file_finder_find_file.png
Binary files differ
diff --git a/doc/workflow/forking/branch_select.png b/doc/user/project/repository/img/forking_workflow_branch_select.png
index 0ea5410f832..0ea5410f832 100644
--- a/doc/workflow/forking/branch_select.png
+++ b/doc/user/project/repository/img/forking_workflow_branch_select.png
Binary files differ
diff --git a/doc/workflow/img/forking_workflow_choose_namespace.png b/doc/user/project/repository/img/forking_workflow_choose_namespace.png
index eb023ca85f2..eb023ca85f2 100644
--- a/doc/workflow/img/forking_workflow_choose_namespace.png
+++ b/doc/user/project/repository/img/forking_workflow_choose_namespace.png
Binary files differ
diff --git a/doc/workflow/img/forking_workflow_fork_button.png b/doc/user/project/repository/img/forking_workflow_fork_button.png
index 7fb07529b6d..7fb07529b6d 100644
--- a/doc/workflow/img/forking_workflow_fork_button.png
+++ b/doc/user/project/repository/img/forking_workflow_fork_button.png
Binary files differ
diff --git a/doc/workflow/forking/merge_request.png b/doc/user/project/repository/img/forking_workflow_merge_request.png
index 43851203f3f..43851203f3f 100644
--- a/doc/workflow/forking/merge_request.png
+++ b/doc/user/project/repository/img/forking_workflow_merge_request.png
Binary files differ
diff --git a/doc/workflow/img/forking_workflow_path_taken_error.png b/doc/user/project/repository/img/forking_workflow_path_taken_error.png
index ef62d0ab6a9..ef62d0ab6a9 100644
--- a/doc/workflow/img/forking_workflow_path_taken_error.png
+++ b/doc/user/project/repository/img/forking_workflow_path_taken_error.png
Binary files differ
diff --git a/doc/workflow/img/copy_ssh_public_key_button.png b/doc/user/project/repository/img/repository_mirroring_copy_ssh_public_key_button.png
index e20dae09a4d..e20dae09a4d 100644
--- a/doc/workflow/img/copy_ssh_public_key_button.png
+++ b/doc/user/project/repository/img/repository_mirroring_copy_ssh_public_key_button.png
Binary files differ
diff --git a/doc/workflow/img/repository_mirroring_force_update.png b/doc/user/project/repository/img/repository_mirroring_force_update.png
index 1e6dcb9ea08..1e6dcb9ea08 100644
--- a/doc/workflow/img/repository_mirroring_force_update.png
+++ b/doc/user/project/repository/img/repository_mirroring_force_update.png
Binary files differ
diff --git a/doc/workflow/img/repository_mirroring_pull_settings_lower.png b/doc/user/project/repository/img/repository_mirroring_pull_settings_lower.png
index a3e0b74ddf8..a3e0b74ddf8 100644
--- a/doc/workflow/img/repository_mirroring_pull_settings_lower.png
+++ b/doc/user/project/repository/img/repository_mirroring_pull_settings_lower.png
Binary files differ
diff --git a/doc/workflow/img/repository_mirroring_pull_settings_upper.png b/doc/user/project/repository/img/repository_mirroring_pull_settings_upper.png
index 8e15b5a0784..8e15b5a0784 100644
--- a/doc/workflow/img/repository_mirroring_pull_settings_upper.png
+++ b/doc/user/project/repository/img/repository_mirroring_pull_settings_upper.png
Binary files differ
diff --git a/doc/workflow/img/repository_mirroring_push_settings.png b/doc/user/project/repository/img/repository_mirroring_push_settings.png
index 3c0eacaa2df..3c0eacaa2df 100644
--- a/doc/workflow/img/repository_mirroring_push_settings.png
+++ b/doc/user/project/repository/img/repository_mirroring_push_settings.png
Binary files differ
diff --git a/doc/user/project/repository/index.md b/doc/user/project/repository/index.md
index c14783b72bd..5a6e011220c 100644
--- a/doc/user/project/repository/index.md
+++ b/doc/user/project/repository/index.md
@@ -11,7 +11,8 @@ A repository is part of a [project](../index.md), which has a lot of other featu
## Create a repository
To create a new repository, all you need to do is
-[create a new project](../../../gitlab-basics/create-project.md).
+[create a new project](../../../gitlab-basics/create-project.md) or
+[fork an existing project](forking_workflow.md).
Once you create a new project, you can add new files via UI
(read the section below) or via command line.
@@ -55,7 +56,7 @@ To get started with the command line, please read through the
### Find files
-Use GitLab's [file finder](../../../workflow/file_finder.md) to search for files in a repository.
+Use GitLab's [file finder](file_finder.md) to search for files in a repository.
### Supported markup languages and extensions
diff --git a/doc/user/project/repository/repository_mirroring.md b/doc/user/project/repository/repository_mirroring.md
new file mode 100644
index 00000000000..a682983ab83
--- /dev/null
+++ b/doc/user/project/repository/repository_mirroring.md
@@ -0,0 +1,430 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/repository_mirroring.html'
+---
+
+# Repository mirroring
+
+Repository mirroring allows for mirroring of repositories to and from external sources. It can be
+used to mirror branches, tags, and commits between repositories.
+
+A repository mirror at GitLab will be updated automatically. You can also manually trigger an update
+at most once every 5 minutes.
+
+## Overview
+
+Repository mirroring is useful when you want to use a repository outside of GitLab.
+
+There are two kinds of repository mirroring supported by GitLab:
+
+- Push: for mirroring a GitLab repository to another location.
+- Pull: for mirroring a repository from another location to GitLab. **(STARTER)**
+
+When the mirror repository is updated, all new branches, tags, and commits will be visible in the
+project's activity feed.
+
+Users with at least [developer access](../../permissions.md) to the project can also force an
+immediate update, unless:
+
+- The mirror is already being updated.
+- 5 minutes haven't elapsed since its last update.
+
+## Use cases
+
+The following are some possible use cases for repository mirroring:
+
+- You migrated to GitLab but still need to keep your project in another source. In that case, you
+ can simply set it up to mirror to GitLab (pull) and all the essential history of commits, tags,
+ and branches will be available in your GitLab instance. **(STARTER)**
+- You have old projects in another source that you don't use actively anymore, but don't want to
+ remove for archiving purposes. In that case, you can create a push mirror so that your active
+ GitLab repository can push its changes to the old location.
+
+## Pushing to a remote repository **(CORE)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/249) in GitLab Enterprise Edition 8.7.
+> - [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18715) in 10.8.
+
+For an existing project, you can set up push mirroring as follows:
+
+1. Navigate to your project's **Settings > Repository** and expand the **Mirroring repositories** section.
+1. Enter a repository URL.
+1. Select **Push** from the **Mirror direction** dropdown.
+1. Select an authentication method from the **Authentication method** dropdown, if necessary.
+1. Check the **Only mirror protected branches** box, if necessary.
+1. Click the **Mirror repository** button to save the configuration.
+
+![Repository mirroring push settings screen](img/repository_mirroring_push_settings.png)
+
+When push mirroring is enabled, only push commits directly to the mirrored repository to prevent the
+mirror diverging. All changes will end up in the mirrored repository whenever:
+
+- Commits are pushed to GitLab.
+- A [forced update](#forcing-an-update-core) is initiated.
+
+Changes pushed to files in the repository are automatically pushed to the remote mirror at least:
+
+- Within five minutes of being received.
+- Within one minute if **Only mirror protected branches** is enabled.
+
+In the case of a diverged branch, you will see an error indicated at the **Mirroring repositories**
+section.
+
+### Push only protected branches **(CORE)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3350) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
+> - [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18715) in 10.8.
+
+You can choose to only push your protected branches from GitLab to your remote repository.
+
+To use this option, check the **Only mirror protected branches** box when creating a repository
+mirror.
+
+## Setting up a push mirror from GitLab to GitHub **(CORE)**
+
+To set up a mirror from GitLab to GitHub, you need to follow these steps:
+
+1. Create a [GitHub personal access token](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) with the `public_repo` box checked.
+1. Fill in the **Git repository URL** field using this format: `https://<your_github_username>@github.com/<your_github_group>/<your_github_project>.git`.
+1. Fill in **Password** field with your GitHub personal access token.
+1. Click the **Mirror repository** button.
+
+The mirrored repository will be listed. For example, `https://*****:*****@github.com/<your_github_group>/<your_github_project>.git`.
+
+The repository will push soon. To force a push, click the appropriate button.
+
+## Setting up a push mirror to another GitLab instance with 2FA activated
+
+1. On the destination GitLab instance, create a [personal access token](../../profile/personal_access_tokens.md) with `API` scope.
+1. On the source GitLab instance:
+ 1. Fill in the **Git repository URL** field using this format: `https://oauth2@<destination host>/<your_gitlab_group_or_name>/<your_gitlab_project>.git`.
+ 1. Fill in **Password** field with the GitLab personal access token created on the destination GitLab instance.
+ 1. Click the **Mirror repository** button.
+
+## Pulling from a remote repository **(STARTER)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/51) in GitLab Enterprise Edition 8.2.
+> - [Added Git LFS support](https://gitlab.com/gitlab-org/gitlab/issues/10871) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.11.
+
+NOTE: **Note:** This feature [is available for free](https://gitlab.com/gitlab-org/gitlab/issues/10361) to
+GitLab.com users until March 22nd, 2020.
+
+You can set up a repository to automatically have its branches, tags, and commits updated from an
+upstream repository.
+
+This is useful when a repository you're interested in is located on a different server, and you want
+to be able to browse its content and its activity using the familiar GitLab interface.
+
+To configure mirror pulling for an existing project:
+
+1. Navigate to your project's **Settings > Repository** and expand the **Mirroring repositories**
+ section.
+1. Enter a repository URL.
+1. Select **Pull** from the **Mirror direction** dropdown.
+1. Select an authentication method from the **Authentication method** dropdown, if necessary.
+1. If necessary, check the following boxes:
+ - **Overwrite diverged branches**.
+ - **Trigger pipelines for mirror updates**.
+ - **Only mirror protected branches**.
+1. Click the **Mirror repository** button to save the configuration.
+
+![Repository mirroring pull settings screen - upper part](img/repository_mirroring_pull_settings_upper.png)
+
+---
+
+![Repository mirroring pull settings screen - lower part](img/repository_mirroring_pull_settings_lower.png)
+
+Because GitLab is now set to pull changes from the upstream repository, you should not push commits
+directly to the repository on GitLab. Instead, any commits should be pushed to the upstream repository.
+Changes pushed to the upstream repository will be pulled into the GitLab repository, either:
+
+- Automatically within a certain period of time.
+- When a [forced update](#forcing-an-update-core) is initiated.
+
+CAUTION: **Caution:**
+If you do manually update a branch in the GitLab repository, the branch will become diverged from
+upstream and GitLab will no longer automatically update this branch to prevent any changes from being lost.
+
+### How it works
+
+Once the pull mirroring feature has been enabled for a repository, the repository is added to a queue.
+
+Once per minute, a Sidekiq cron job schedules repository mirrors to update, based on:
+
+- The capacity available. This is determined by Sidekiq settings. For GitLab.com, see [GitLab.com Sidekiq settings](../../gitlab_com/index.md#sidekiq).
+- The number of repository mirrors already in the queue that are due to be updated. Being due depends on when the repository mirror was last updated and how many times it's been retried.
+
+Repository mirrors are updated as Sidekiq becomes available to process them. If the process of updating the repository mirror:
+
+- Succeeds, an update will be enqueued again with at least a 30 minute wait.
+- Fails (for example, a branch diverged from upstream), it will be attempted again later. Mirrors can fail
+ up to 14 times before they will not be enqueued for update again.
+
+### SSH authentication
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/2551) for Pull mirroring in [GitLab Starter](https://about.gitlab.com/pricing/) 9.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/22982) for Push mirroring in [GitLab Core](https://about.gitlab.com/pricing/) 11.6
+
+SSH authentication is mutual:
+
+- You have to prove to the server that you're allowed to access the repository.
+- The server also has to prove to *you* that it's who it claims to be.
+
+You provide your credentials as a password or public key. The server that the
+other repository resides on provides its credentials as a "host key", the
+fingerprint of which needs to be verified manually.
+
+If you're mirroring over SSH (that is, using an `ssh://` URL), you can authenticate using:
+
+- Password-based authentication, just as over HTTPS.
+- Public key authentication. This is often more secure than password authentication,
+ especially when the other repository supports [Deploy Keys](../../../ssh/README.md#deploy-keys).
+
+To get started:
+
+1. Navigate to your project's **Settings > Repository** and expand the **Mirroring repositories** section.
+1. Enter an `ssh://` URL for mirroring.
+
+NOTE: **Note:**
+SCP-style URLs (that is, `git@example.com:group/project.git`) are not supported at this time.
+
+Entering the URL adds two buttons to the page:
+
+- **Detect host keys**.
+- **Input host keys manually**.
+
+If you click the:
+
+- **Detect host keys** button, GitLab will fetch the host keys from the server and display the fingerprints.
+- **Input host keys manually** button, a field is displayed where you can paste in host keys.
+
+Assuming you used the former, you now need to verify that the fingerprints are
+those you expect. GitLab.com and other code hosting sites publish their
+fingerprints in the open for you to check:
+
+- [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html#regions-fingerprints)
+- [Bitbucket](https://confluence.atlassian.com/bitbucket/ssh-keys-935365775.html)
+- [GitHub](https://help.github.com/en/articles/githubs-ssh-key-fingerprints)
+- [GitLab.com](../../gitlab_com/index.md#ssh-host-keys-fingerprints)
+- [Launchpad](https://help.launchpad.net/SSHFingerprints)
+- [Savannah](http://savannah.gnu.org/maintenance/SshAccess/)
+- [SourceForge](https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/)
+
+Other providers will vary. If you're running self-managed GitLab, or otherwise
+have access to the server for the other repository, you can securely gather the
+key fingerprints:
+
+```sh
+$ cat /etc/ssh/ssh_host*pub | ssh-keygen -E md5 -l -f -
+256 MD5:f4:28:9f:23:99:15:21:1b:bf:ed:1f:8e:a0:76:b2:9d root@example.com (ECDSA)
+256 MD5:e6:eb:45:8a:3c:59:35:5f:e9:5b:80:12:be:7e:22:73 root@example.com (ED25519)
+2048 MD5:3f:72:be:3d:62:03:5c:62:83:e8:6e:14:34:3a:85:1d root@example.com (RSA)
+```
+
+NOTE: **Note:**
+You may need to exclude `-E md5` for some older versions of SSH.
+
+When mirroring the repository, GitLab will now check that at least one of the
+stored host keys matches before connecting. This can prevent malicious code from
+being injected into your mirror, or your password being stolen.
+
+### SSH public key authentication
+
+To use SSH public key authentication, you'll also need to choose that option
+from the **Authentication method** dropdown. When the mirror is created,
+GitLab generates a 4096-bit RSA key that can be copied by clicking the **Copy SSH public key** button.
+
+![Repository mirroring copy SSH public key to clipboard button](img/repository_mirroring_copy_ssh_public_key_button.png)
+
+You then need to add the public SSH key to the other repository's configuration:
+
+- If the other repository is hosted on GitLab, you should add the public SSH key
+ as a [Deploy Key](../../../ssh/README.md#deploy-keys).
+- If the other repository is hosted elsewhere, you may need to add the key to
+ your user's `authorized_keys` file. Paste the entire public SSH key into the
+ file on its own line and save it.
+
+If you need to change the key at any time, you can remove and re-add the mirror
+to generate a new key. You'll have to update the other repository with the new
+key to keep the mirror running.
+
+### Overwrite diverged branches **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/4559) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
+
+You can choose to always update your local branches with remote versions, even if they have
+diverged from the remote.
+
+CAUTION: **Caution:**
+For mirrored branches, enabling this option results in the loss of local changes.
+
+To use this option, check the **Overwrite diverged branches** box when creating a repository mirror.
+
+### Only mirror protected branches **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3326) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
+
+You can choose to pull mirror only the protected branches from your remote repository to GitLab.
+Non-protected branches are not mirrored and can diverge.
+
+To use this option, check the **Only mirror protected branches** box when creating a repository mirror.
+
+### Hard failure **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3117) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.2.
+
+Once the mirroring process is unsuccessfully retried 14 times in a row, it will get marked as hard
+failed. This will become visible in either the:
+
+- Project's main dashboard.
+- Pull mirror settings page.
+
+When a project is hard failed, it will no longer get picked up for mirroring. A user can resume the
+project mirroring again by [Forcing an update](#forcing-an-update-core).
+
+### Trigger update using API **(STARTER)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3453) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
+
+Pull mirroring uses polling to detect new branches and commits added upstream, often minutes
+afterwards. If you notify GitLab by [API](../../../api/projects.md#start-the-pull-mirroring-process-for-a-project-starter),
+updates will be pulled immediately.
+
+For more information, see [Start the pull mirroring process for a Project](../../../api/projects.md#start-the-pull-mirroring-process-for-a-project-starter).
+
+## Forcing an update **(CORE)**
+
+While mirrors are scheduled to update automatically, you can always force an update by using the
+update button which is available on the **Mirroring repositories** section of the **Repository Settings** page.
+
+![Repository mirroring force update user interface](img/repository_mirroring_force_update.png)
+
+## Bidirectional mirroring **(STARTER)**
+
+CAUTION: **Caution:**
+Bidirectional mirroring may cause conflicts.
+
+If you configure a GitLab repository to both pull from, and push to, the same remote source, there
+is no guarantee that either repository will update correctly. If you set up a repository for
+bidirectional mirroring, you should prepare for the likely conflicts by deciding who will resolve
+them and how they will be resolved.
+
+Rewriting any mirrored commit on either remote will cause conflicts and mirroring to fail. This can
+be prevented by:
+
+- [Pulling only protected branches](#only-mirror-protected-branches-starter).
+- [Pushing only protected branches](#push-only-protected-branches-core).
+
+You should [protect the branches](../protected_branches.md) you wish to mirror on both
+remotes to prevent conflicts caused by rewriting history.
+
+Bidirectional mirroring also creates a race condition where commits made close together to the same
+branch causes conflicts. The race condition can be mitigated by reducing the mirroring delay by using
+a [Push event webhook](../integrations/webhooks.md#push-events) to trigger an immediate
+pull to GitLab. Push mirroring from GitLab is rate limited to once per minute when only push mirroring
+protected branches.
+
+### Preventing conflicts using a `pre-receive` hook
+
+CAUTION: **Warning:**
+The solution proposed will negatively impact the performance of
+Git push operations because they will be proxied to the upstream Git
+repository.
+
+A server-side `pre-receive` hook can be used to prevent the race condition
+described above by only accepting the push after first pushing the commit to
+the upstream Git repository. In this configuration one Git repository acts as
+the authoritative upstream, and the other as downstream. The `pre-receive` hook
+will be installed on the downstream repository.
+
+Read about [configuring custom Git hooks](../../../administration/custom_hooks.md) on the GitLab server.
+
+A sample `pre-receive` hook is provided below.
+
+```bash
+#!/usr/bin/env bash
+
+# --- Assume only one push mirror target
+# Push mirroring remotes are named `remote_mirror_<id>`, this finds the first remote and uses that.
+TARGET_REPO=$(git remote | grep -m 1 remote_mirror)
+
+proxy_push()
+{
+ # --- Arguments
+ OLDREV=$(git rev-parse $1)
+ NEWREV=$(git rev-parse $2)
+ REFNAME="$3"
+
+ # --- Pattern of branches to proxy pushes
+ whitelisted=$(expr "$branch" : "\(master\)")
+
+ case "$refname" in
+ refs/heads/*)
+ branch=$(expr "$refname" : "refs/heads/\(.*\)")
+
+ if [ "$whitelisted" = "$branch" ]; then
+ error="$(git push --quiet $TARGET_REPO $NEWREV:$REFNAME 2>&1)"
+ fail=$?
+
+ if [ "$fail" != "0" ]; then
+ echo >&2 ""
+ echo >&2 " Error: updates were rejected by upstream server"
+ echo >&2 " This is usually caused by another repository pushing changes"
+ echo >&2 " to the same ref. You may want to first integrate remote changes"
+ echo >&2 ""
+ return
+ fi
+ fi
+ ;;
+ esac
+}
+
+# Allow dual mode: run from the command line just like the update hook, or
+# if no arguments are given then run as a hook script
+if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
+ # Output to the terminal in command line mode - if someone wanted to
+ # resend an email; they could redirect the output to sendmail
+ # themselves
+ PAGER= proxy_push $2 $3 $1
+else
+ # Push is proxied upstream one ref at a time. Because of this it is possible
+ # for some refs to succeed, and others to fail. This will result in a failed
+ # push.
+ while read oldrev newrev refname
+ do
+ proxy_push $oldrev $newrev $refname
+ done
+fi
+```
+
+### Mirroring with Perforce Helix via Git Fusion **(STARTER)**
+
+CAUTION: **Warning:**
+Bidirectional mirroring should not be used as a permanent configuration. Refer to
+[Migrating from Perforce Helix](../import/perforce.md) for alternative migration approaches.
+
+[Git Fusion](https://www.perforce.com/manuals/git-fusion/#Git-Fusion/section_avy_hyc_gl.html) provides a Git interface
+to [Perforce Helix](https://www.perforce.com/products) which can be used by GitLab to bidirectionally
+mirror projects with GitLab. This may be useful in some situations when migrating from Perforce Helix
+to GitLab where overlapping Perforce Helix workspaces cannot be migrated simultaneously to GitLab.
+
+If using mirroring with Perforce Helix, you should only mirror protected branches. Perforce Helix
+will reject any pushes that rewrite history. Only the fewest number of branches should be mirrored
+due to the performance limitations of Git Fusion.
+
+When configuring mirroring with Perforce Helix via Git Fusion, the following Git Fusion
+settings are recommended:
+
+- `change-pusher` should be disabled. Otherwise, every commit will be rewritten as being committed
+ by the mirroring account, rather than being mapped to existing Perforce Helix users or the `unknown_git` user.
+- `unknown_git` user will be used as the commit author if the GitLab user does not exist in
+ Perforce Helix.
+
+Read about [Git Fusion settings on Perforce.com](https://www.perforce.com/manuals/git-fusion/Content/Git-Fusion/section_vss_bdw_w3.html#section_zdp_zz1_3l).
+
+## Troubleshooting
+
+Should an error occur during a push, GitLab will display an "Error" highlight for that repository. Details on the error can then be seen by hovering over the highlight text.
+
+### 13:Received RST_STREAM with error code 2 with GitHub
+
+If you receive an "13:Received RST_STREAM with error code 2" while mirroring to a GitHub repository, your GitHub settings might be set to block pushes that expose your email address used in commits. Either set your email address on GitHub to be public, or disable the [Block command line pushes that expose my email](https://github.com/settings/emails) setting.
diff --git a/doc/user/project/time_tracking.md b/doc/user/project/time_tracking.md
new file mode 100644
index 00000000000..9cdee0f2b5a
--- /dev/null
+++ b/doc/user/project/time_tracking.md
@@ -0,0 +1,92 @@
+---
+type: reference
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/time_tracking.html'
+---
+
+# Time Tracking
+
+> Introduced in GitLab 8.14.
+
+Time Tracking allows you to track estimates and time spent on issues and merge
+requests within GitLab.
+
+## Overview
+
+Time Tracking allows you to:
+
+- Record the time spent working on an issue or a merge request.
+- Add an estimate of the amount of time needed to complete an issue or a merge
+ request.
+
+You don't have to indicate an estimate to enter the time spent, and vice versa.
+
+Data about time tracking is shown on the issue/merge request sidebar, as shown
+below.
+
+![Time tracking in the sidebar](img/time_tracking_sidebar_v8_16.png)
+
+## How to enter data
+
+Time Tracking uses two [quick actions](quick_actions.md)
+that GitLab introduced with this new feature: `/spend` and `/estimate`.
+
+Quick actions can be used in the body of an issue or a merge request, but also
+in a comment in both an issue or a merge request.
+
+Below is an example of how you can use those new quick actions inside a comment.
+
+![Time tracking example in a comment](img/time_tracking_example_v12_2.png)
+
+Adding time entries (time spent or estimates) is limited to project members.
+
+### Estimates
+
+To enter an estimate, write `/estimate`, followed by the time. For example, if
+you need to enter an estimate of 3 days, 5 hours and 10 minutes, you would write
+`/estimate 3d 5h 10m`. Time units that we support are listed at the bottom of
+this help page.
+
+Every time you enter a new time estimate, any previous time estimates will be
+overridden by this new value. There should only be one valid estimate in an
+issue or a merge request.
+
+To remove an estimation entirely, use `/remove_estimate`.
+
+### Time spent
+
+To enter a time spent, use `/spend 3d 5h 10m`.
+
+Every new time spent entry will be added to the current total time spent for the
+issue or the merge request.
+
+You can remove time by entering a negative amount: `/spend -3d` will remove 3
+days from the total time spent. You can't go below 0 minutes of time spent,
+so GitLab will automatically reset the time spent if you remove a larger amount
+of time compared to the time that was entered already.
+
+To remove all the time spent at once, use `/remove_time_spent`.
+
+## Configuration
+
+The following time units are available:
+
+- Months (mo)
+- Weeks (w)
+- Days (d)
+- Hours (h)
+- Minutes (m)
+
+Default conversion rates are 1mo = 4w, 1w = 5d and 1d = 8h.
+
+### Limit displayed units to hours **(CORE ONLY)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/29469/) in GitLab 12.1.
+
+In GitLab self-managed instances, the display of time units can be limited to
+hours through the option in **Admin Area > Settings > Preferences** under **Localization**.
+
+With this option enabled, `75h` is displayed instead of `1w 4d 3h`.
+
+## Other interesting links
+
+- [Time Tracking landing page in the GitLab handbook](https://about.gitlab.com/solutions/time-tracking/)
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index 8d7b4a429aa..33f920440ac 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -99,8 +99,8 @@ quickly access issues and merge requests created or assigned to you within that
## To-Do List
-Your [To-Do List](../../workflow/todos.md#gitlab-to-do-list) can be searched by "to do" and "done".
-You can [filter](../../workflow/todos.md#filtering-your-to-do-list) them per project,
+Your [To-Do List](../todos.md#gitlab-to-do-list) can be searched by "to do" and "done".
+You can [filter](../todos.md#filtering-your-to-do-list) them per project,
author, type, and action. Also, you can sort them by
[**Label priority**](../../user/project/labels.md#label-priority),
**Last created** and **Oldest created**.
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
new file mode 100644
index 00000000000..54e7938d8f7
--- /dev/null
+++ b/doc/user/shortcuts.md
@@ -0,0 +1,135 @@
+---
+type: reference
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/shortcuts.html'
+---
+
+# GitLab keyboard shortcuts
+
+GitLab has many useful keyboard shortcuts to make it easier to access different features.
+You can see the quick reference sheet within GitLab itself with <kbd>Shift</kbd> + <kbd>?</kbd>.
+
+The [Global Shortcuts](#global-shortcuts) work from any area of GitLab, but you must
+be in specific pages for the other shortcuts to be available, as explained in each
+section below.
+
+## Global Shortcuts
+
+These shortcuts are available in most areas of GitLab
+
+| Keyboard Shortcut | Description |
+| ------------------------------- | ----------- |
+| <kbd>?</kbd> | Show/hide shortcut reference sheet. |
+| <kbd>Shift</kbd> + <kbd>p</kbd> | Go to your Projects page. |
+| <kbd>Shift</kbd> + <kbd>g</kbd> | Go to your Groups page. |
+| <kbd>Shift</kbd> + <kbd>a</kbd> | Go to your Activity page. |
+| <kbd>Shift</kbd> + <kbd>l</kbd> | Go to your Milestones page. |
+| <kbd>Shift</kbd> + <kbd>s</kbd> | Go to your Snippets page. |
+| <kbd>s</kbd> | Put cursor in the issues/merge requests search. |
+| <kbd>Shift</kbd> + <kbd>i</kbd> | Go to your Issues page. |
+| <kbd>Shift</kbd> + <kbd>m</kbd> | Go to your Merge requests page.|
+| <kbd>Shift</kbd> + <kbd>t</kbd> | Go to your To-Do List page. |
+| <kbd>p</kbd> + <kbd>b</kbd> | Show/hide the Performance Bar. |
+
+Additionally, the following shortcuts are available when editing text in text fields,
+for example comments, replies, or issue and merge request descriptions:
+
+| Keyboard Shortcut | Description |
+| ---------------------------------------------------------------------- | ----------- |
+| <kbd>↑</kbd> | Edit your last comment. You must be in a blank text field below a thread, and you must already have at least one comment in the thread. |
+| <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>p</kbd> | Toggle Markdown preview, when editing text in a text field that has **Write** and **Preview** tabs at the top. |
+
+## Project
+
+These shortcuts are available from any page within a project. You must type them
+relatively quickly to work, and they will take you to another page in the project.
+
+| Keyboard Shortcut | Description |
+| --------------------------- | ----------- |
+| <kbd>g</kbd> + <kbd>p</kbd> | Go to the project home page (**Project > Details**). |
+| <kbd>g</kbd> + <kbd>v</kbd> | Go to the project activity feed (**Project > Activity**). |
+| <kbd>g</kbd> + <kbd>r</kbd> | Go to the project releases list (**Project > Releases**). |
+| <kbd>g</kbd> + <kbd>f</kbd> | Go to the [project files](#project-files) list (**Repository > Files**). |
+| <kbd>t</kbd> | Go to the project file search page. (**Repository > Files**, click **Find Files**). |
+| <kbd>g</kbd> + <kbd>c</kbd> | Go to the project commits list (**Repository > Commits**). |
+| <kbd>g</kbd> + <kbd>n</kbd> | Go to the [repository graph](#repository-graph) page (**Repository > Graph**). |
+| <kbd>g</kbd> + <kbd>d</kbd> | Go to repository charts (**Repository > Charts**). |
+| <kbd>g</kbd> + <kbd>i</kbd> | Go to the project issues list (**Issues > List**). |
+| <kbd>i</kbd> | Go to the New Issue page (**Issues**, click **New Issue** ). |
+| <kbd>g</kbd> + <kbd>b</kbd> | Go to the project issue boards list (**Issues > Boards**). |
+| <kbd>g</kbd> + <kbd>m</kbd> | Go to the project merge requests list (**Merge Requests**). |
+| <kbd>g</kbd> + <kbd>j</kbd> | Go to the CI/CD jobs list (**CI/CD > Jobs**). |
+| <kbd>g</kbd> + <kbd>l</kbd> | Go to the project metrics (**Operations > Metrics**). |
+| <kbd>g</kbd> + <kbd>e</kbd> | Go to the project environments (**Operations > Environments**). |
+| <kbd>g</kbd> + <kbd>k</kbd> | Go to the project Kubernetes cluster integration page (**Operations > Kubernetes**). Note that you must have at least [`maintainer` permissions](permissions.md) to access this page. |
+| <kbd>g</kbd> + <kbd>s</kbd> | Go to the project snippets list (**Snippets**). |
+| <kbd>g</kbd> + <kbd>w</kbd> | Go to the project wiki (**Wiki**), if enabled. |
+
+### Issues and Merge Requests
+
+These shortcuts are available when viewing issues and merge requests.
+
+| Keyboard Shortcut | Description |
+| ---------------------------- | ----------- |
+| <kbd>e</kbd> | Edit description. |
+| <kbd>a</kbd> | Change assignee. |
+| <kbd>m</kbd> | Change milestone. |
+| <kbd>l</kbd> | Change label. |
+| <kbd>r</kbd> | Start writing a comment. If any text is selected, it will be quoted in the comment. Can't be used to reply within a thread. |
+| <kbd>n</kbd> | Move to next unresolved discussion (Merge requests only). |
+| <kbd>p</kbd> | Move to previous unresolved discussion (Merge requests only). |
+| <kbd>]</kbd> or <kbd>j</kbd> | Move to next file (Merge requests only). |
+| <kbd>[</kbd> or <kbd>k</kbd> | Move to previous file (Merge requests only). |
+
+### Project Files
+
+These shortcuts are available when browsing the files in a project (navigate to
+**Repository** > **Files**):
+
+| Keyboard Shortcut | Description |
+| ----------------- | ----------- |
+| <kbd>↑</kbd> | Move selection up. |
+| <kbd>↓</kbd> | Move selection down. |
+| <kbd>enter</kbd> | Open selection. |
+| <kbd>esc</kbd> | Go back to file list screen (only while searching for files, **Repository > Files** then click on **Find File**). |
+| <kbd>y</kbd> | Go to file permalink (only while viewing a file). |
+
+### Web IDE
+
+These shortcuts are available when editing a file with the [Web IDE](project/web_ide/index.md):
+
+| Keyboard Shortcut | Description |
+| ------------------------------------------------------- | ----------- |
+| <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> + <kbd>p</kbd> | Search for, and then open another file for editing. |
+| <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> + <kbd>Enter</kbd> | Commit (when editing the commit message). |
+
+### Repository Graph
+
+These shortcuts are available when viewing the project [repository graph](project/repository/index.md#repository-graph)
+page (navigate to **Repository > Graph**):
+
+| Keyboard Shortcut | Description |
+| ------------------------------------------------------------------ | ----------- |
+| <kbd>←</kbd> or <kbd>h</kbd> | Scroll left. |
+| <kbd>→</kbd> or <kbd>l</kbd> | Scroll right. |
+| <kbd>↑</kbd> or <kbd>k</kbd> | Scroll up. |
+| <kbd>↓</kbd> or <kbd>j</kbd> | Scroll down. |
+| <kbd>Shift</kbd> + <kbd>↑</kbd> or <kbd>Shift</kbd> + <kbd>k</kbd> | Scroll to top. |
+| <kbd>Shift</kbd> + <kbd>↓</kbd> or <kbd>Shift</kbd> + <kbd>j</kbd> | Scroll to bottom. |
+
+### Wiki pages
+
+This shortcut is available when viewing a [wiki page](project/wiki/index.md):
+
+| Keyboard Shortcut | Description |
+| ----------------- | ----------- |
+| <kbd>e</kbd> | Edit wiki page. |
+
+## Epics **(ULTIMATE)**
+
+These shortcuts are available when viewing [Epics](group/epics/index.md):
+
+| Keyboard Shortcut | Description |
+| ----------------- | ----------- |
+| <kbd>r</kbd> | Start writing a comment. If any text is selected, it will be quoted in the comment. Can't be used to reply within a thread. |
+| <kbd>e</kbd> | Edit description. |
+| <kbd>l</kbd> | Change label. |
diff --git a/doc/user/todos.md b/doc/user/todos.md
new file mode 100644
index 00000000000..22a6d07aedb
--- /dev/null
+++ b/doc/user/todos.md
@@ -0,0 +1,142 @@
+---
+disqus_identifier: 'https://docs.gitlab.com/ee/workflow/todos.html'
+---
+
+# GitLab To-Do List
+
+> [Introduced][ce-2817] in GitLab 8.5.
+
+When you log into GitLab, you normally want to see where you should spend your
+time, take some action, or know what you need to keep an eye on without
+a huge pile of e-mail notifications. GitLab is where you do your work,
+so being able to get started quickly is important.
+
+Your To-Do List offers a chronological list of items that are waiting for your input, all
+in a simple dashboard.
+
+![To Do screenshot showing a list of items to check on](img/todos_index.png)
+
+You can quickly access your To-Do List by clicking the checkmark icon next to the
+search bar in the top navigation. If the count is:
+
+- Less than 100, the number in blue is the number of To-Do items.
+- 100 or more, the number displays as 99+. The exact number displays
+ on the To-Do List.
+you still have open. Otherwise, the number displays as 99+. The exact number
+displays on the To-Do List.
+
+![To Do icon](img/todos_icon.png)
+
+## What triggers a To Do
+
+A To Do displays on your To-Do List when:
+
+- An issue or merge request is assigned to you
+- You are `@mentioned` in the description or comment of an:
+ - Issue
+ - Merge Request
+ - Epic **(ULTIMATE)**
+- You are `@mentioned` in a comment on a commit
+- A job in the CI pipeline running for your merge request failed, but this
+ job is not allowed to fail
+- An open merge request becomes unmergeable due to conflict, and you are either:
+ - The author
+ - Have set it to automatically merge once the pipeline succeeds
+
+To-do triggers are not affected by [GitLab Notification Email settings](../workflow/notifications.md).
+
+NOTE: **Note:**
+When a user no longer has access to a resource related to a To Do (like an issue, merge request, project, or group) the related To-Do items are deleted within the next hour for security reasons. The delete is delayed to prevent data loss, in case the user's access was revoked by mistake.
+
+### Directly addressing a To Do
+
+> [Introduced][ce-7926] in GitLab 9.0.
+
+If you are mentioned at the start of a line, the To Do you receive will be listed
+as 'directly addressed'. For example, in this comment:
+
+```markdown
+@alice What do you think? cc: @bob
+
+- @carol can you please have a look?
+
+>>>
+@dan what do you think?
+>>>
+
+@erin @frank thank you!
+```
+
+The people receiving directly addressed To-Do items are `@alice`, `@erin`, and
+`@frank`. Directly addressed To-Do items only differ from mentions in their type
+for filtering purposes; otherwise, they appear as normal.
+
+### Manually creating a To Do
+
+You can also add the following to your To-Do List by clicking the **Add a To Do** button on an:
+
+- Issue
+- Merge Request
+- Epic **(ULTIMATE)**
+
+![Adding a To Do from the issuable sidebar](img/todos_add_todo_sidebar.png)
+
+## Marking a To Do as done
+
+Any action to the following will mark the corresponding To Do as done:
+
+- Issue
+- Merge Request
+- Epic **(ULTIMATE)**
+
+Actions that dismiss To-Do items include:
+
+- Changing the assignee
+- Changing the milestone
+- Adding/removing a label
+- Commenting on the issue
+
+Your To-Do List is personal, and items are only marked as done if the action comes from
+you. If you close the issue or merge request, your To Do is automatically
+marked as done.
+
+To prevent other users from closing issues without you being notified, if someone else closes, merges, or takes action on the any of the following, your To Do will remain pending:
+
+- Issue
+- Merge request
+- Epic **(ULTIMATE)**
+
+There is just one To Do for each of these, so mentioning a user a hundred times in an issue will only trigger one To Do.
+
+If no action is needed, you can manually mark the To Do as done by clicking the
+corresponding **Done** button, and it will disappear from your To-Do List.
+
+![A To Do in the To-Do List](img/todos_todo_list_item.png)
+
+You can also mark a To Do as done by clicking the **Mark as done** button in the sidebar of the following:
+
+- Issue
+- Merge Request
+- Epic **(ULTIMATE)**
+
+![Mark as done from the issuable sidebar](img/todos_mark_done_sidebar.png)
+
+You can mark all your To-Do items as done at once by clicking the **Mark all as
+done** button.
+
+## Filtering your To-Do List
+
+There are four kinds of filters you can use on your To-Do List.
+
+| Filter | Description |
+| ------- | ----------- |
+| Project | Filter by project |
+| Group | Filter by group |
+| Author | Filter by the author that triggered the To Do |
+| Type | Filter by issue, merge request, or epic **(ULTIMATE)** |
+| Action | Filter by the action that triggered the To Do |
+
+You can also filter by more than one of these at the same time. The possible Actions are `Any Action`, `Assigned`, `Mentioned`, `Added`, `Pipelines`, and `Directly Addressed`, [as described above](#what-triggers-a-to-do).
+
+[ce-2817]: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/2817
+[ce-7926]: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/7926
diff --git a/doc/workflow/README.md b/doc/workflow/README.md
index c6396672e59..63f7b83f388 100644
--- a/doc/workflow/README.md
+++ b/doc/workflow/README.md
@@ -5,11 +5,9 @@ comments: false
# Workflow
- [Automatic issue closing](../user/project/issues/managing_issues.md#closing-issues-automatically)
-- [Change your time zone](timezone.md)
- [Cycle Analytics](../user/project/cycle_analytics.md)
- [Description templates](../user/project/description_templates.md)
-- [Feature branch workflow](workflow.md)
-- [GitLab Flow](gitlab_flow.md)
+- [Feature branch workflow](../gitlab-basics/feature_branch_workflow.md)
- [Groups](../user/group/index.md)
- Issues - The GitLab Issue Tracker is an advanced and complete tool for
tracking the evolution of a new idea or the process of solving a problem.
@@ -17,22 +15,17 @@ comments: false
- [Confidential issues](../user/project/issues/confidential_issues.md)
- [Due date for issues](../user/project/issues/due_dates.md)
- [Issue Board](../user/project/issue_board.md)
-- [Keyboard shortcuts](shortcuts.md)
-- [File finder](file_finder.md)
+- [File finder](../user/project/repository/file_finder.md)
- [File lock](../user/project/file_lock.md) **(PREMIUM)**
- [Labels](../user/project/labels.md)
-- [Issue weight](issue_weight.md) **(STARTER)**
-- [Notification emails](notifications.md)
- [Projects](../user/project/index.md)
-- [Project forking workflow](forking_workflow.md)
+- [Project forking workflow](../user/project/repository/forking_workflow.md)
- [Project users](../user/project/members/index.md)
- [Protected branches](../user/project/protected_branches.md)
- [Protected tags](../user/project/protected_tags.md)
- [Quick Actions](../user/project/quick_actions.md)
- [Sharing projects with groups](../user/project/members/share_project_with_groups.md)
-- [Time tracking](time_tracking.md)
- [Web Editor](../user/project/repository/web_editor.md)
-- [Releases](releases.md)
- [Milestones](../user/project/milestones/index.md)
- [Merge Requests](../user/project/merge_requests/index.md)
- [Authorization for merge requests](../user/project/merge_requests/authorization_for_merge_requests.md)
@@ -45,10 +38,7 @@ comments: false
- ["Work In Progress" merge requests](../user/project/merge_requests/work_in_progress_merge_requests.md)
- [Fast-forward merge requests](../user/project/merge_requests/fast_forward_merge.md)
- [Merge request approvals](../user/project/merge_requests/merge_request_approvals.md) **(STARTER)**
-- [Repository mirroring](repository_mirroring.md) **(STARTER)**
- [Service Desk](../user/project/service_desk.md) **(PREMIUM)**
-- [Manage large binaries with Git LFS](lfs/manage_large_binaries_with_git_lfs.md)
-- [Importing from SVN, GitHub, Bitbucket, etc](importing/README.md)
-- [Todos](todos.md)
+- [Importing from SVN, GitHub, Bitbucket, etc](../user/project/import/index.md)
- [Snippets](../user/snippets.md)
- [Subgroups](../user/group/subgroups/index.md)
diff --git a/doc/workflow/file_finder.md b/doc/workflow/file_finder.md
index 8eb705b5363..f7098c88fd1 100644
--- a/doc/workflow/file_finder.md
+++ b/doc/workflow/file_finder.md
@@ -1,41 +1,5 @@
-# File finder
+---
+redirect_to: '../user/project/repository/file_finder.md'
+---
-> [Introduced][gh-9889] in GitLab 8.4.
-
-The file finder feature allows you to quickly shortcut your way when you are
-searching for a file in a repository using the GitLab UI.
-
-You can find the **Find File** button when in the **Files** section of a
-project.
-
-![Find file button](img/file_finder_find_button.png)
-
-For those who prefer to keep their fingers on the keyboard, there is a
-[shortcut button](shortcuts.md) as well, which you can invoke from _anywhere_
-in a project.
-
-Press `t` to launch the File search function when in **Issues**,
-**Merge requests**, **Milestones**, even the project's settings.
-
-Start typing what you are searching for and watch the magic happen. With the
-up/down arrows, you go up and down the results, with `Esc` you close the search
-and go back to **Files**.
-
-## How it works
-
-The File finder feature is powered by the [Fuzzy filter](https://github.com/jeancroy/fuzz-aldrin-plus) library.
-
-It implements a fuzzy search with highlight, and tries to provide intuitive
-results by recognizing patterns that people use while searching.
-
-For example, consider the [GitLab CE repository][ce] and that we want to open
-the `app/controllers/admin/deploy_keys_controller.rb` file.
-
-Using fuzzy search, we start by typing letters that get us closer to the file.
-
-**Protip:** To narrow down your search, include `/` in your search terms.
-
-![Find file button](img/file_finder_find_file.png)
-
-[gh-9889]: https://github.com/gitlabhq/gitlabhq/pull/9889 "File finder pull request"
-[ce]: https://gitlab.com/gitlab-org/gitlab-foss/tree/master "GitLab CE repository"
+This document was moved to [another location](../user/project/repository/file_finder.md).
diff --git a/doc/workflow/forking_workflow.md b/doc/workflow/forking_workflow.md
index 48be38b2eca..fa617d859a5 100644
--- a/doc/workflow/forking_workflow.md
+++ b/doc/workflow/forking_workflow.md
@@ -1,51 +1,5 @@
-# Project forking workflow
+---
+redirect_to: '../user/project/repository/forking_workflow.md'
+---
-Forking a project to your own namespace is useful if you have no write
-access to the project you want to contribute to. If you do have write
-access or can request it, we recommend working together in the same
-repository since it is simpler. See our [GitLab Flow](gitlab_flow.md)
-document more information about using branches to work together.
-
-## Creating a fork
-
-Forking a project is in most cases a two-step process.
-
-1. Click on the fork button located located in between the star and clone buttons on the project's home page.
-
- ![Fork button](img/forking_workflow_fork_button.png)
-
-1. Once you do that, you'll be presented with a screen where you can choose
- the namespace to fork to. Only namespaces (groups and your own
- namespace) where you have write access to, will be shown. Click on the
- namespace to create your fork there.
-
- ![Choose namespace](img/forking_workflow_choose_namespace.png)
-
- **Note:**
- If the namespace you chose to fork the project to has another project with
- the same path name, you will be presented with a warning that the forking
- could not be completed. Try to resolve the error before repeating the forking
- process.
-
- ![Path taken error](img/forking_workflow_path_taken_error.png)
-
-After the forking is done, you can start working on the newly created
-repository. There, you will have full [Owner](../user/permissions.md)
-access, so you can set it up as you please.
-
-## Merging upstream
-
-Once you are ready to send your code back to the main project, you need
-to create a merge request. Choose your forked project's main branch as
-the source and the original project's main branch as the destination and
-create the [merge request](merge_requests.md).
-
-![Selecting branches](forking/branch_select.png)
-
-You can then assign the merge request to someone to have them review
-your changes. Upon pressing the 'Submit Merge Request' button, your
-changes will be added to the repository and branch you're merging into.
-
-![New merge request](forking/merge_request.png)
-
-[gitlab flow]: https://about.gitlab.com/blog/2014/09/29/gitlab-flow/ "GitLab Flow blog post"
+This document was moved to [another location](../user/project/repository/forking_workflow.md).
diff --git a/doc/workflow/git_annex.md b/doc/workflow/git_annex.md
index 84d49569a95..e54d52ea70d 100644
--- a/doc/workflow/git_annex.md
+++ b/doc/workflow/git_annex.md
@@ -1,238 +1,5 @@
-# Git annex
-
-> **Warning:** GitLab has [completely
-removed][deprecate-annex-issue] in GitLab 9.0 (2017/03/22).
-Read through the [migration guide from git-annex to Git LFS][guide].
-
-The biggest limitation of Git, compared to some older centralized version
-control systems, has been the maximum size of the repositories.
-
-The general recommendation is to not have Git repositories larger than 1GB to
-preserve performance. Although GitLab has no limit (some repositories in GitLab
-are over 50GB!), we subscribe to the advice to keep repositories as small as
-you can.
-
-Not being able to version control large binaries is a big problem for many
-larger organizations.
-Videos, photos, audio, compiled binaries and many other types of files are too
-large. As a workaround, people keep artwork-in-progress in a Dropbox folder and
-only check in the final result. This results in using outdated files, not
-having a complete history and increases the risk of losing work.
-
-This problem is solved in GitLab Enterprise Edition by integrating the
-[git-annex] application.
-
-`git-annex` allows managing large binaries with Git without checking the
-contents into Git.
-You check-in only a symlink that contains the SHA-1 of the large binary. If you
-need the large binary, you can sync it from the GitLab server over `rsync`, a
-very fast file copying tool.
-
-## GitLab git-annex Configuration
-
-`git-annex` is disabled by default in GitLab. Below you will find the
-configuration options required to enable it.
-
-### Requirements
-
-`git-annex` needs to be installed both on the server and the client side.
-
-For Debian-like systems (e.g., Debian, Ubuntu) this can be achieved by running:
-
-```
-sudo apt-get update && sudo apt-get install git-annex
-```
-
-For RedHat-like systems (e.g., CentOS, RHEL) this can be achieved by running:
-
-```
-sudo yum install epel-release && sudo yum install git-annex
-```
-
-### Configuration for Omnibus packages
-
-For Omnibus GitLab packages, only one configuration setting is needed.
-The Omnibus package will internally set the correct options in all locations.
-
-1. In `/etc/gitlab/gitlab.rb` add the following line:
-
- ```ruby
- gitlab_shell['git_annex_enabled'] = true
- ```
-
-1. Save the file and [reconfigure GitLab][] for the changes to take effect.
-
-### Configuration for installations from source
-
-There are 2 settings to enable git-annex on your GitLab server.
-
-One is located in `config/gitlab.yml` of the GitLab repository and the other
-one is located in `config.yml` of GitLab Shell.
-
-1. In `config/gitlab.yml` add or edit the following lines:
-
- ```yaml
- gitlab_shell:
- git_annex_enabled: true
- ```
-
-1. In `config.yml` of GitLab Shell add or edit the following lines:
-
- ```yaml
- git_annex_enabled: true
- ```
-
-1. Save the files and [restart GitLab][] for the changes to take effect.
-
-## Using GitLab git-annex
-
-> **Note:**
-> Your Git remotes must be using the SSH protocol, not HTTP(S).
-
-Here is an example workflow of uploading a very large file and then checking it
-into your Git repository:
-
-```bash
-git clone git@example.com:group/project.git
-
-git annex init 'My Laptop' # initialize the annex project and give an optional description
-cp ~/tmp/debian.iso ./ # copy a large file into the current directory
-git annex add debian.iso # add the large file to git annex
-git commit -am "Add Debian iso" # commit the file metadata
-git annex sync --content # sync the Git repo and large file to the GitLab server
-```
-
-The output should look like this:
-
-```
-commit
-On branch master
-Your branch is ahead of 'origin/master' by 1 commit.
- (use "git push" to publish your local commits)
-nothing to commit, working tree clean
-ok
-pull origin
-remote: Counting objects: 5, done.
-remote: Compressing objects: 100% (4/4), done.
-remote: Total 5 (delta 2), reused 0 (delta 0)
-Unpacking objects: 100% (5/5), done.
-From example.com:group/project
- 497842b..5162f80 git-annex -> origin/git-annex
-ok
-(merging origin/git-annex into git-annex...)
-(recording state in git...)
-copy debian.iso (checking origin...) (to origin...)
-SHA256E-s26214400--8092b3d482fb1b7a5cf28c43bc1425c8f2d380e86869c0686c49aa7b0f086ab2.iso
- 26,214,400 100% 638.88kB/s 0:00:40 (xfr#1, to-chk=0/1)
-ok
-pull origin
-ok
-(recording state in git...)
-push origin
-Counting objects: 15, done.
-Delta compression using up to 4 threads.
-Compressing objects: 100% (13/13), done.
-Writing objects: 100% (15/15), 1.64 KiB | 0 bytes/s, done.
-Total 15 (delta 1), reused 0 (delta 0)
-To example.com:group/project.git
- * [new branch] git-annex -> synced/git-annex
- * [new branch] master -> synced/master
-ok
-```
-
-Your files can be found in the `master` branch, but you'll notice that there
-are more branches created by the `annex sync` command.
-
-Git Annex will also create a new directory at `.git/annex/` and will record the
-tracked files in the `.git/config` file. The files you assign to be tracked
-with `git-annex` will not affect the existing `.git/config` records. The files
-are turned into symbolic links that point to data in `.git/annex/objects/`.
-
-The `debian.iso` file in the example will contain the symbolic link:
-
-```
-.git/annex/objects/ZW/1k/SHA256E-s82701--6384039733b5035b559efd5a2e25a493ab6e09aabfd5162cc03f6f0ec238429d.png/SHA256E-s82701--6384039733b5035b559efd5a2e25a493ab6e09aabfd5162cc03f6f0ec238429d.iso
-```
-
-Use `git annex info` to retrieve the information about the local copy of your
-repository.
-
+---
+redirect_to: '../administration/git_annex.md'
---
-Downloading a single large file is also very simple:
-
-```bash
-git clone git@gitlab.example.com:group/project.git
-
-git annex sync # sync Git branches but not the large file
-git annex get debian.iso # download the large file
-```
-
-To download all files:
-
-```bash
-git clone git@gitlab.example.com:group/project.git
-
-git annex sync --content # sync Git branches and download all the large files
-```
-
-By using `git-annex` without GitLab, anyone that can access the server can also
-access the files of all projects, but GitLab Annex ensures that you can only
-access files of projects you have access to (developer, maintainer, or owner role).
-
-## How it works
-
-Internally GitLab uses [GitLab Shell] to handle SSH access and this was a great
-integration point for `git-annex`.
-There is a setting in GitLab Shell so you can disable GitLab Annex support
-if you want to.
-
-## Troubleshooting tips
-
-Differences in version of `git-annex` on the GitLab server and on local machines
-can cause `git-annex` to raise unpredicted warnings and errors.
-
-Consult the [Annex upgrade page][annex-upgrade] for more information about
-the differences between versions. You can find out which version is installed
-on your server by navigating to <https://pkgs.org/download/git-annex> and
-searching for your distribution.
-
-Although there is no general guide for `git-annex` errors, there are a few tips
-on how to go around the warnings.
-
-### `git-annex-shell: Not a git-annex or gcrypt repository`
-
-This warning can appear on the initial `git annex sync --content` and is caused
-by differences in `git-annex-shell`. You can read more about it
-[in this git-annex issue][issue].
-
-One important thing to note is that despite the warning, the `sync` succeeds
-and the files are pushed to the GitLab repository.
-
-If you get hit by this, you can run the following command inside the repository
-that the warning was raised:
-
-```
-git config remote.origin.annex-ignore false
-```
-
-Consecutive runs of `git annex sync --content` **should not** produce this
-warning and the output should look like this:
-
-```
-commit ok
-pull origin
-ok
-pull origin
-ok
-push origin
-```
-
-[annex-upgrade]: https://git-annex.branchable.com/upgrades/
-[deprecate-annex-issue]: https://gitlab.com/gitlab-org/gitlab/issues/1648
-[git-annex]: https://git-annex.branchable.com/ "git-annex website"
-[gitlab shell]: https://gitlab.com/gitlab-org/gitlab-shell "GitLab Shell repository"
-[guide]: lfs/migrate_from_git_annex_to_git_lfs.html
-[issue]: https://git-annex.branchable.com/forum/Error_from_git-annex-shell_on_creation_of_gcrypt_special_remote/ "git-annex issue"
-[reconfigure GitLab]: ../administration/restart_gitlab.md#omnibus-gitlab-reconfigure
-[restart GitLab]: ../administration/restart_gitlab.md#installations-from-source
+This document was moved to [another location](../administration/git_annex.md).
diff --git a/doc/workflow/git_lfs.md b/doc/workflow/git_lfs.md
index da217b0a5da..0a8c33c264c 100644
--- a/doc/workflow/git_lfs.md
+++ b/doc/workflow/git_lfs.md
@@ -1,5 +1,5 @@
---
-redirect_to: 'lfs/manage_large_binaries_with_git_lfs.md'
+redirect_to: '../administration/lfs/manage_large_binaries_with_git_lfs.md'
---
-This document was moved to [another location](lfs/manage_large_binaries_with_git_lfs.md).
+This document was moved to [another location](../administration/lfs/manage_large_binaries_with_git_lfs.md).
diff --git a/doc/workflow/gitlab_flow.md b/doc/workflow/gitlab_flow.md
index e3568d6489d..e03281c0ffc 100644
--- a/doc/workflow/gitlab_flow.md
+++ b/doc/workflow/gitlab_flow.md
@@ -1,326 +1,5 @@
-# Introduction to GitLab Flow
+---
+redirect_to: '../topics/gitlab_flow.md'
+---
-![GitLab Flow](img/gitlab_flow.png)
-
-Git allows a wide variety of branching strategies and workflows.
-Because of this, many organizations end up with workflows that are too complicated, not clearly defined, or not integrated with issue tracking systems.
-Therefore, we propose GitLab flow as a clearly defined set of best practices.
-It combines [feature-driven development](https://en.wikipedia.org/wiki/Feature-driven_development) and [feature branches](https://martinfowler.com/bliki/FeatureBranch.html) with issue tracking.
-
-Organizations coming to Git from other version control systems frequently find it hard to develop a productive workflow.
-This article describes GitLab flow, which integrates the Git workflow with an issue tracking system.
-It offers a simple, transparent, and effective way to work with Git.
-
-![Four stages (working copy, index, local repo, remote repo) and three steps between them](img/four_stages.png)
-
-When converting to Git, you have to get used to the fact that it takes three steps to share a commit with colleagues.
-Most version control systems have only one step: committing from the working copy to a shared server.
-In Git, you add files from the working copy to the staging area. After that, you commit them to your local repo.
-The third step is pushing to a shared remote repository.
-After getting used to these three steps, the next challenge is the branching model.
-
-![Multiple long-running branches and merging in all directions](img/messy_flow.png)
-
-Since many organizations new to Git have no conventions for how to work with it, their repositories can quickly become messy.
-The biggest problem is that many long-running branches emerge that all contain part of the changes.
-People have a hard time figuring out which branch has the latest code, or which branch to deploy to production.
-Frequently, the reaction to this problem is to adopt a standardized pattern such as [Git flow](https://nvie.com/posts/a-successful-git-branching-model/) and [GitHub flow](http://scottchacon.com/2011/08/31/github-flow.html).
-We think there is still room for improvement. In this document, we describe a set of practices we call GitLab flow.
-
-For a video introduction of how this works in GitLab, see [GitLab Flow](https://youtu.be/InKNIvky2KE).
-
-## Git flow and its problems
-
-![Git Flow timeline by Vincent Driessen, used with permission](img/gitdashflow.png)
-
-Git flow was one of the first proposals to use Git branches, and it has received a lot of attention.
-It suggests a `master` branch and a separate `develop` branch, as well as supporting branches for features, releases, and hotfixes.
-The development happens on the `develop` branch, moves to a release branch, and is finally merged into the `master` branch.
-
-Git flow is a well-defined standard, but its complexity introduces two problems.
-The first problem is that developers must use the `develop` branch and not `master`. `master` is reserved for code that is released to production.
-It is a convention to call your default branch `master` and to mostly branch from and merge to this.
-Since most tools automatically use the `master` branch as the default, it is annoying to have to switch to another branch.
-
-The second problem of Git flow is the complexity introduced by the hotfix and release branches.
-These branches can be a good idea for some organizations but are overkill for the vast majority of them.
-Nowadays, most organizations practice continuous delivery, which means that your default branch can be deployed.
-Continuous delivery removes the need for hotfix and release branches, including all the ceremony they introduce.
-An example of this ceremony is the merging back of release branches.
-Though specialized tools do exist to solve this, they require documentation and add complexity.
-Frequently, developers make mistakes such as merging changes only into `master` and not into the `develop` branch.
-The reason for these errors is that Git flow is too complicated for most use cases.
-For example, many projects do releases but don't need to do hotfixes.
-
-## GitHub flow as a simpler alternative
-
-![Master branch with feature branches merged in](img/github_flow.png)
-
-In reaction to Git flow, GitHub created a simpler alternative.
-[GitHub flow](https://guides.github.com/introduction/flow/index.html) has only feature branches and a `master` branch.
-This flow is clean and straightforward, and many organizations have adopted it with great success.
-Atlassian recommends [a similar strategy](https://www.atlassian.com/blog/git/simple-git-workflow-is-simple), although they rebase feature branches.
-Merging everything into the `master` branch and frequently deploying means you minimize the amount of unreleased code, which is in line with lean and continuous delivery best practices.
-However, this flow still leaves a lot of questions unanswered regarding deployments, environments, releases, and integrations with issues.
-With GitLab flow, we offer additional guidance for these questions.
-
-## Production branch with GitLab flow
-
-![Master branch and production branch with an arrow that indicates a deployment](img/production_branch.png)
-
-GitHub flow assumes you can deploy to production every time you merge a feature branch.
-While this is possible in some cases, such as SaaS applications, there are many cases where this is not possible.
-One case is where you don't control the timing of a release, for example, an iOS application that is released when it passes App Store validation.
-Another case is when you have deployment windows &mdash; for example, workdays from 10&nbsp;AM to 4&nbsp;PM when the operations team is at full capacity &mdash; but you also merge code at other times.
-In these cases, you can make a production branch that reflects the deployed code.
-You can deploy a new version by merging `master` into the production branch.
-If you need to know what code is in production, you can just checkout the production branch to see.
-The approximate time of deployment is easily visible as the merge commit in the version control system.
-This time is pretty accurate if you automatically deploy your production branch.
-If you need a more exact time, you can have your deployment script create a tag on each deployment.
-This flow prevents the overhead of releasing, tagging, and merging that happens with Git flow.
-
-## Environment branches with GitLab flow
-
-![Multiple branches with the code cascading from one to another](img/environment_branches.png)
-
-It might be a good idea to have an environment that is automatically updated to the `master` branch.
-Only, in this case, the name of this environment might differ from the branch name.
-Suppose you have a staging environment, a pre-production environment, and a production environment.
-In this case, deploy the `master` branch to staging.
-To deploy to pre-production, create a merge request from the `master` branch to the pre-production branch.
-Go live by merging the pre-production branch into the production branch.
-This workflow, where commits only flow downstream, ensures that everything is tested in all environments.
-If you need to cherry-pick a commit with a hotfix, it is common to develop it on a feature branch and merge it into `master` with a merge request.
-In this case, do not delete the feature branch yet.
-If `master` passes automatic testing, you then merge the feature branch into the other branches.
-If this is not possible because more manual testing is required, you can send merge requests from the feature branch to the downstream branches.
-
-## Release branches with GitLab flow
-
-![Master and multiple release branches that vary in length with cherry-picks from master](img/release_branches.png)
-
-You only need to work with release branches if you need to release software to the outside world.
-In this case, each branch contains a minor version, for example, 2-3-stable, 2-4-stable, etc.
-Create stable branches using `master` as a starting point, and branch as late as possible.
-By doing this, you minimize the length of time during which you have to apply bug fixes to multiple branches.
-After announcing a release branch, only add serious bug fixes to the branch.
-If possible, first merge these bug fixes into `master`, and then cherry-pick them into the release branch.
-If you start by merging into the release branch, you might forget to cherry-pick them into `master`, and then you'd encounter the same bug in subsequent releases.
-Merging into `master` and then cherry-picking into release is called an "upstream first" policy, which is also practiced by [Google](https://www.chromium.org/chromium-os/chromiumos-design-docs/upstream-first) and [Red Hat](https://www.redhat.com/en/blog/a-community-for-using-openstack-with-red-hat-rdo).
-Every time you include a bug fix in a release branch, increase the patch version (to comply with [Semantic Versioning](https://semver.org/)) by setting a new tag.
-Some projects also have a stable branch that points to the same commit as the latest released branch.
-In this flow, it is not common to have a production branch (or Git flow `master` branch).
-
-## Merge/pull requests with GitLab flow
-
-![Merge request with inline comments](img/mr_inline_comments.png)
-
-Merge or pull requests are created in a Git management application. They ask an assigned person to merge two branches.
-Tools such as GitHub and Bitbucket choose the name "pull request" since the first manual action is to pull the feature branch.
-Tools such as GitLab and others choose the name "merge request" since the final action is to merge the feature branch.
-In this article, we'll refer to them as merge requests.
-
-If you work on a feature branch for more than a few hours, it is good to share the intermediate result with the rest of the team.
-To do this, create a merge request without assigning it to anyone.
-Instead, mention people in the description or a comment, for example, "/cc @mark @susan."
-This indicates that the merge request is not ready to be merged yet, but feedback is welcome.
-Your team members can comment on the merge request in general or on specific lines with line comments.
-The merge request serves as a code review tool, and no separate code review tools should be needed.
-If the review reveals shortcomings, anyone can commit and push a fix.
-Usually, the person to do this is the creator of the merge request.
-The diff in the merge request automatically updates when new commits are pushed to the branch.
-
-When you are ready for your feature branch to be merged, assign the merge request to the person who knows most about the codebase you are changing.
-Also, mention any other people from whom you would like feedback.
-After the assigned person feels comfortable with the result, they can merge the branch.
-If the assigned person does not feel comfortable, they can request more changes or close the merge request without merging.
-
-In GitLab, it is common to protect the long-lived branches, e.g., the `master` branch, so that [most developers can't modify them](../permissions/permissions.md).
-So, if you want to merge into a protected branch, assign your merge request to someone with maintainer permissions.
-
-After you merge a feature branch, you should remove it from the source control software.
-In GitLab, you can do this when merging.
-Removing finished branches ensures that the list of branches shows only work in progress.
-It also ensures that if someone reopens the issue, they can use the same branch name without causing problems.
-
-NOTE: **Note:**
-When you reopen an issue you need to create a new merge request.
-
-![Remove checkbox for branch in merge requests](img/remove_checkbox.png)
-
-## Issue tracking with GitLab flow
-
-![Merge request with the branch name "15-require-a-password-to-change-it" and assignee field shown](img/merge_request.png)
-
-GitLab flow is a way to make the relation between the code and the issue tracker more transparent.
-
-Any significant change to the code should start with an issue that describes the goal.
-Having a reason for every code change helps to inform the rest of the team and to keep the scope of a feature branch small.
-In GitLab, each change to the codebase starts with an issue in the issue tracking system.
-If there is no issue yet, create the issue, as long as the change will take a significant amount of work, i.e., more than 1 hour.
-In many organizations, raising an issue is part of the development process because they are used in sprint planning.
-The issue title should describe the desired state of the system.
-For example, the issue title "As an administrator, I want to remove users without receiving an error" is better than "Admin can't remove users."
-
-When you are ready to code, create a branch for the issue from the `master` branch.
-This branch is the place for any work related to this change.
-
-NOTE: **Note:**
-The name of a branch might be dictated by organizational standards.
-
-When you are done or want to discuss the code, open a merge request.
-A merge request is an online place to discuss the change and review the code.
-
-If you open the merge request but do not assign it to anyone, it is a "Work In Progress" merge request.
-These are used to discuss the proposed implementation but are not ready for inclusion in the `master` branch yet.
-Start the title of the merge request with `[WIP]` or `WIP:` to prevent it from being merged before it's ready.
-
-When you think the code is ready, assign the merge request to a reviewer.
-The reviewer can merge the changes when they think the code is ready for inclusion in the `master` branch.
-When they press the merge button, GitLab merges the code and creates a merge commit that makes this event easily visible later on.
-Merge requests always create a merge commit, even when the branch could be merged without one.
-This merge strategy is called "no fast-forward" in Git.
-After the merge, delete the feature branch since it is no longer needed.
-In GitLab, this deletion is an option when merging.
-
-Suppose that a branch is merged but a problem occurs and the issue is reopened.
-In this case, it is no problem to reuse the same branch name since the first branch was deleted when it was merged.
-At any time, there is at most one branch for every issue.
-It is possible that one feature branch solves more than one issue.
-
-## Linking and closing issues from merge requests
-
-![Merge request showing the linked issues that will be closed](img/close_issue_mr.png)
-
-Link to issues by mentioning them in commit messages or the description of a merge request, for example, "Fixes #16" or "Duck typing is preferred. See #12."
-GitLab then creates links to the mentioned issues and creates comments in the issues linking back to the merge request.
-
-To automatically close linked issues, mention them with the words "fixes" or "closes," for example, "fixes #14" or "closes #67." GitLab closes these issues when the code is merged into the default branch.
-
-If you have an issue that spans across multiple repositories, create an issue for each repository and link all issues to a parent issue.
-
-## Squashing commits with rebase
-
-![Vim screen showing the rebase view](img/rebase.png)
-
-With Git, you can use an interactive rebase (`rebase -i`) to squash multiple commits into one or reorder them.
-This functionality is useful if you want to replace a couple of small commits with a single commit, or if you want to make the order more logical.
-
-However, you should never rebase commits you have pushed to a remote server.
-Rebasing creates new commits for all your changes, which can cause confusion because the same change would have multiple identifiers.
-It also causes merge errors for anyone working on the same branch because their history would not match with yours.
-Also, if someone has already reviewed your code, rebasing makes it hard to tell what changed since the last review.
-
-You should also never rebase commits authored by other people.
-Not only does this rewrite history, but it also loses authorship information.
-Rebasing prevents the other authors from being attributed and sharing part of the [`git blame`](https://git-scm.com/docs/git-blame).
-
-If a merge involves many commits, it may seem more difficult to undo.
-You might think to solve this by squashing all the changes into one commit before merging, but as discussed earlier, it is a bad idea to rebase commits that you have already pushed.
-Fortunately, there is an easy way to undo a merge with all its commits.
-The way to do this is by reverting the merge commit.
-Preserving this ability to revert a merge is a good reason to always use the "no fast-forward" (`--no-ff`) strategy when you merge manually.
-
-NOTE: **Note:**
-If you revert a merge commit and then change your mind, revert the revert commit to redo the merge.
-Git does not allow you to merge the code again otherwise.
-
-## Reducing merge commits in feature branches
-
-![List of sequential merge commits](img/merge_commits.png)
-
-Having lots of merge commits can make your repository history messy.
-Therefore, you should try to avoid merge commits in feature branches.
-Often, people avoid merge commits by just using rebase to reorder their commits after the commits on the `master` branch.
-Using rebase prevents a merge commit when merging `master` into your feature branch, and it creates a neat linear history.
-However, as discussed in [the section about rebasing](#squashing-commits-with-rebase), you should never rebase commits you have pushed to a remote server.
-This restriction makes it impossible to rebase work in progress that you already shared with your team, which is something we recommend.
-
-Rebasing also creates more work, since every time you rebase, you have to resolve similar conflicts.
-Sometimes you can reuse recorded resolutions (`rerere`), but merging is better since you only have to resolve conflicts once.
-Atlassian has a more thorough explanation of the tradeoffs between merging and rebasing [on their blog](https://www.atlassian.com/blog/git/git-team-workflows-merge-or-rebase).
-
-A good way to prevent creating many merge commits is to not frequently merge `master` into the feature branch.
-There are three reasons to merge in `master`: utilizing new code, resolving merge conflicts, and updating long-running branches.
-
-If you need to utilize some code that was introduced in `master` after you created the feature branch, you can often solve this by just cherry-picking a commit.
-
-If your feature branch has a merge conflict, creating a merge commit is a standard way of solving this.
-
-NOTE: **Note:**
-Sometimes you can use .gitattributes to reduce merge conflicts.
-For example, you can set your changelog file to use the [union merge driver](https://git-scm.com/docs/gitattributes#gitattributes-union) so that multiple new entries don't conflict with each other.
-
-The last reason for creating merge commits is to keep long-running feature branches up-to-date with the latest state of the project.
-The solution here is to keep your feature branches short-lived.
-Most feature branches should take less than one day of work.
-If your feature branches often take more than a day of work, try to split your features into smaller units of work.
-
-If you need to keep a feature branch open for more than a day, there are a few strategies to keep it up-to-date.
-One option is to use continuous integration (CI) to merge in `master` at the start of the day.
-Another option is to only merge in from well-defined points in time, for example, a tagged release.
-You could also use [feature toggles](https://martinfowler.com/bliki/FeatureToggle.html) to hide incomplete features so you can still merge back into `master` every day.
-
-> **Note:** Don't confuse automatic branch testing with continuous integration.
-> Martin Fowler makes this distinction in [his article about feature branches](https://martinfowler.com/bliki/FeatureBranch.html):
->
-> "I've heard people say they are doing CI because they are running builds, perhaps using a CI server, on every branch with every commit.
-> That's continuous building, and a Good Thing, but there's no *integration*, so it's not CI."
-
-In conclusion, you should try to prevent merge commits, but not eliminate them.
-Your codebase should be clean, but your history should represent what actually happened.
-Developing software happens in small, messy steps, and it is OK to have your history reflect this.
-You can use tools to view the network graphs of commits and understand the messy history that created your code.
-If you rebase code, the history is incorrect, and there is no way for tools to remedy this because they can't deal with changing commit identifiers.
-
-## Commit often and push frequently
-
-Another way to make your development work easier is to commit often.
-Every time you have a working set of tests and code, you should make a commit.
-Splitting up work into individual commits provides context for developers looking at your code later.
-Smaller commits make it clear how a feature was developed, and they make it easy to roll back to a specific good point in time or to revert one code change without reverting several unrelated changes.
-
-Committing often also makes it easy to share your work, which is important so that everyone is aware of what you are working on.
-You should push your feature branch frequently, even when it is not yet ready for review.
-By sharing your work in a feature branch or [a merge request](#mergepull-requests-with-gitlab-flow), you prevent your team members from duplicating work.
-Sharing your work before it's complete also allows for discussion and feedback about the changes, which can help improve the code before it gets to review.
-
-## How to write a good commit message
-
-![Good and bad commit message](img/good_commit.png)
-
-A commit message should reflect your intention, not just the contents of the commit.
-It is easy to see the changes in a commit, so the commit message should explain why you made those changes.
-An example of a good commit message is: "Combine templates to reduce duplicate code in the user views."
-The words "change," "improve," "fix," and "refactor" don't add much information to a commit message.
-For example, "Improve XML generation" could be better written as "Properly escape special characters in XML generation."
-For more information about formatting commit messages, please see this excellent [blog post by Tim Pope](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
-
-## Testing before merging
-
-![Merge requests showing the test states: red, yellow, and green](img/ci_mr.png)
-
-In old workflows, the continuous integration (CI) server commonly ran tests on the `master` branch only.
-Developers had to ensure their code did not break the `master` branch.
-When using GitLab flow, developers create their branches from this `master` branch, so it is essential that it never breaks.
-Therefore, each merge request must be tested before it is accepted.
-CI software like Travis CI and GitLab CI show the build results right in the merge request itself to make this easy.
-
-There is one drawback to testing merge requests: the CI server only tests the feature branch itself, not the merged result.
-Ideally, the server could also test the `master` branch after each change.
-However, retesting on every commit to `master` is computationally expensive and means you are more frequently waiting for test results.
-Since feature branches should be short-lived, testing just the branch is an acceptable risk.
-If new commits in `master` cause merge conflicts with the feature branch, merge `master` back into the branch to make the CI server re-run the tests.
-As said before, if you often have feature branches that last for more than a few days, you should make your issues smaller.
-
-## Working with feature branches
-
-![Shell output showing git pull output](img/git_pull.png)
-
-When creating a feature branch, always branch from an up-to-date `master`.
-If you know before you start that your work depends on another branch, you can also branch from there.
-If you need to merge in another branch after starting, explain the reason in the merge commit.
-If you have not pushed your commits to a shared location yet, you can also incorporate changes by rebasing on `master` or another feature branch.
-Do not merge from upstream again if your code can work and merge cleanly without doing so.
-Merging only when needed prevents creating merge commits in your feature branch that later end up littering the `master` history.
+This document was moved to [another location](../topics/gitlab_flow.md).
diff --git a/doc/workflow/issue_weight.md b/doc/workflow/issue_weight.md
index 79b8e5f5164..94eb38356e8 100644
--- a/doc/workflow/issue_weight.md
+++ b/doc/workflow/issue_weight.md
@@ -1,21 +1,5 @@
-# Issue weight **(STARTER)**
+---
+redirect_to: '../user/project/issues/issue_weight.md'
+---
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/76) in [GitLab Starter](https://about.gitlab.com/pricing/) 8.3.
-
-When you have a lot of issues, it can be hard to get an overview.
-By adding a weight to each issue, you can get a better idea of how much time,
-value or complexity a given issue has or will cost.
-
-You can set the weight of an issue during its creation, by simply changing the
-value in the dropdown menu. You can set it to a non-negative integer
-value from 0, 1, 2, and so on. (The database stores a 4-byte value, so the
-upper bound is essentially limitless).
-You can remove weight from an issue
-as well.
-
-This value will appear on the right sidebar of an individual issue, as well as
-in the issues page next to a distinctive balance scale icon.
-
-As an added bonus, you can see the total sum of all issues on the milestone page.
-
-![issue page](issue_weight/issue.png)
+This document was moved to [another location](../user/project/issues/issue_weight.md).
diff --git a/doc/workflow/lfs/lfs_administration.md b/doc/workflow/lfs/lfs_administration.md
index 7ad87982501..58c48b4f6e6 100644
--- a/doc/workflow/lfs/lfs_administration.md
+++ b/doc/workflow/lfs/lfs_administration.md
@@ -1,269 +1,5 @@
-# GitLab Git LFS Administration
+---
+redirect_to: '../../administration/lfs/lfs_administration.md'
+---
-Documentation on how to use Git LFS are under [Managing large binary files with Git LFS doc](manage_large_binaries_with_git_lfs.md).
-
-## Requirements
-
-- Git LFS is supported in GitLab starting with version 8.2.
-- Support for object storage, such as AWS S3, was introduced in 10.0.
-- Users need to install [Git LFS client](https://git-lfs.github.com) version 1.0.1 and up.
-
-## Configuration
-
-Git LFS objects can be large in size. By default, they are stored on the server
-GitLab is installed on.
-
-There are various configuration options to help GitLab server administrators:
-
-- Enabling/disabling Git LFS support
-- Changing the location of LFS object storage
-- Setting up object storage supported by [Fog](http://fog.io/about/provider_documentation.html)
-
-### Configuration for Omnibus installations
-
-In `/etc/gitlab/gitlab.rb`:
-
-```ruby
-# Change to true to enable lfs - enabled by default if not defined
-gitlab_rails['lfs_enabled'] = false
-
-# Optionally, change the storage path location. Defaults to
-# `#{gitlab_rails['shared_path']}/lfs-objects`. Which evaluates to
-# `/var/opt/gitlab/gitlab-rails/shared/lfs-objects` by default.
-gitlab_rails['lfs_storage_path'] = "/mnt/storage/lfs-objects"
-```
-
-### Configuration for installations from source
-
-In `config/gitlab.yml`:
-
-```yaml
-# Change to true to enable lfs
- lfs:
- enabled: false
- storage_path: /mnt/storage/lfs-objects
-```
-
-## Storing LFS objects in remote object storage
-
-> [Introduced][ee-2760] in [GitLab Premium][eep] 10.0. Brought to GitLab Core in 10.7.
-
-It is possible to store LFS objects in remote object storage which allows you
-to offload local hard disk R/W operations, and free up disk space significantly.
-GitLab is tightly integrated with `Fog`, so you can refer to its [documentation](http://fog.io/about/provider_documentation.html)
-to check which storage services can be integrated with GitLab.
-You can also use external object storage in a private local network. For example,
-[MinIO](https://min.io/) is a standalone object storage service, is easy to set up, and works well with GitLab instances.
-
-GitLab provides two different options for the uploading mechanism: "Direct upload" and "Background upload".
-
-**Option 1. Direct upload**
-
-1. User pushes an lfs file to the GitLab instance
-1. GitLab-workhorse uploads the file directly to the external object storage
-1. GitLab-workhorse notifies GitLab-rails that the upload process is complete
-
-**Option 2. Background upload**
-
-1. User pushes an lfs file to the GitLab instance
-1. GitLab-rails stores the file in the local file storage
-1. GitLab-rails then uploads the file to the external object storage asynchronously
-
-The following general settings are supported.
-
-| Setting | Description | Default |
-|---------|-------------|---------|
-| `enabled` | Enable/disable object storage | `false` |
-| `remote_directory` | The bucket name where LFS objects will be stored| |
-| `direct_upload` | Set to true to enable direct upload of LFS without the need of local shared storage. Option may be removed once we decide to support only single storage for all files. | `false` |
-| `background_upload` | Set to false to disable automatic upload. Option may be removed once upload is direct to S3 | `true` |
-| `proxy_download` | Set to true to enable proxying all files served. Option allows to reduce egress traffic as this allows clients to download directly from remote storage instead of proxying all data | `false` |
-| `connection` | Various connection options described below | |
-
-The `connection` settings match those provided by [Fog](https://github.com/fog).
-
-Here is a configuration example with S3.
-
-| Setting | Description | example |
-|---------|-------------|---------|
-| `provider` | The provider name | AWS |
-| `aws_access_key_id` | AWS credentials, or compatible | `ABC123DEF456` |
-| `aws_secret_access_key` | AWS credentials, or compatible | `ABC123DEF456ABC123DEF456ABC123DEF456` |
-| `aws_signature_version` | AWS signature version to use. 2 or 4 are valid options. Digital Ocean Spaces and other providers may need 2. | 4 |
-| `enable_signature_v4_streaming` | Set to true to enable HTTP chunked transfers with [AWS v4 signatures](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html). Oracle Cloud S3 needs this to be false | true |
-| `region` | AWS region | us-east-1 |
-| `host` | S3 compatible host for when not using AWS, e.g. `localhost` or `storage.example.com` | s3.amazonaws.com |
-| `endpoint` | Can be used when configuring an S3 compatible service such as [MinIO](https://min.io), by entering a URL such as `http://127.0.0.1:9000` | (optional) |
-| `path_style` | Set to true to use `host/bucket_name/object` style paths instead of `bucket_name.host/object`. Leave as false for AWS S3 | false |
-| `use_iam_profile` | Set to true to use IAM profile instead of access keys | false
-
-Here is a configuration example with GCS.
-
-| Setting | Description | example |
-|---------|-------------|---------|
-| `provider` | The provider name | `Google` |
-| `google_project` | GCP project name | `gcp-project-12345` |
-| `google_client_email` | The email address of the service account | `foo@gcp-project-12345.iam.gserviceaccount.com` |
-| `google_json_key_location` | The json key path | `/path/to/gcp-project-12345-abcde.json` |
-
-NOTE: **Note:**
-The service account must have permission to access the bucket.
-[See more](https://cloud.google.com/storage/docs/authentication)
-
-Here is a configuration example with Rackspace Cloud Files.
-
-| Setting | Description | example |
-|---------|-------------|---------|
-| `provider` | The provider name | `Rackspace` |
-| `rackspace_username` | The username of the Rackspace account with access to the container | `joe.smith` |
-| `rackspace_api_key` | The API key of the Rackspace account with access to the container | `ABC123DEF456ABC123DEF456ABC123DE` |
-| `rackspace_region` | The Rackspace storage region to use, a three letter code from the [list of service access endpoints](https://developer.rackspace.com/docs/cloud-files/v1/general-api-info/service-access/) | `iad` |
-| `rackspace_temp_url_key` | The private key you have set in the Rackspace API for temporary URLs. Read more [here](https://developer.rackspace.com/docs/cloud-files/v1/use-cases/public-access-to-your-cloud-files-account/#tempurl) | `ABC123DEF456ABC123DEF456ABC123DE` |
-
-NOTE: **Note:**
-Regardless of whether the container has public access enabled or disabled, Fog will
-use the TempURL method to grant access to LFS objects. If you see errors in logs referencing
-instantiating storage with a temp-url-key, ensure that you have set they key properly
-on the Rackspace API and in `gitlab.rb`. You can verify the value of the key Rackspace
-has set by sending a GET request with token header to the service access endpoint URL
-and comparing the output of the returned headers.
-
-### Manual uploading to an object storage
-
-There are two ways to manually do the same thing as automatic uploading (described above).
-
-**Option 1: rake task**
-
-```sh
-rake gitlab:lfs:migrate
-```
-
-**Option 2: rails console**
-
-```sh
-$ sudo gitlab-rails console # Login to rails console
-
-> # Upload LFS files manually
-> LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object|
-> lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists?
-> end
-```
-
-### S3 for Omnibus installations
-
-On Omnibus installations, the settings are prefixed by `lfs_object_store_`:
-
-1. Edit `/etc/gitlab/gitlab.rb` and add the following lines by replacing with
- the values you want:
-
- ```ruby
- gitlab_rails['lfs_object_store_enabled'] = true
- gitlab_rails['lfs_object_store_remote_directory'] = "lfs-objects"
- gitlab_rails['lfs_object_store_connection'] = {
- 'provider' => 'AWS',
- 'region' => 'eu-central-1',
- 'aws_access_key_id' => '1ABCD2EFGHI34JKLM567N',
- 'aws_secret_access_key' => 'abcdefhijklmnopQRSTUVwxyz0123456789ABCDE',
- # The below options configure an S3 compatible host instead of AWS
- 'host' => 'localhost',
- 'endpoint' => 'http://127.0.0.1:9000',
- 'path_style' => true
- }
- ```
-
-1. Save the file and [reconfigure GitLab]s for the changes to take effect.
-1. Migrate any existing local LFS objects to the object storage:
-
- ```bash
- gitlab-rake gitlab:lfs:migrate
- ```
-
- This will migrate existing LFS objects to object storage. New LFS objects
- will be forwarded to object storage unless
- `gitlab_rails['lfs_object_store_background_upload']` is set to false.
-
-### S3 for installations from source
-
-For source installations the settings are nested under `lfs:` and then
-`object_store:`:
-
-1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following
- lines:
-
- ```yaml
- lfs:
- enabled: true
- object_store:
- enabled: false
- remote_directory: lfs-objects # Bucket name
- connection:
- provider: AWS
- aws_access_key_id: 1ABCD2EFGHI34JKLM567N
- aws_secret_access_key: abcdefhijklmnopQRSTUVwxyz0123456789ABCDE
- region: eu-central-1
- # Use the following options to configure an AWS compatible host such as Minio
- host: 'localhost'
- endpoint: 'http://127.0.0.1:9000'
- path_style: true
- ```
-
-1. Save the file and [restart GitLab][] for the changes to take effect.
-1. Migrate any existing local LFS objects to the object storage:
-
- ```bash
- sudo -u git -H bundle exec rake gitlab:lfs:migrate RAILS_ENV=production
- ```
-
- This will migrate existing LFS objects to object storage. New LFS objects
- will be forwarded to object storage unless `background_upload` is set to
- false.
-
-### Migrating back to local storage
-
-In order to migrate back to local storage:
-
-1. Set both `direct_upload` and `background_upload` to false under the LFS object storage settings. Don't forget to restart GitLab.
-1. Run `rake gitlab:lfs:migrate_to_local` on your console.
-1. Disable `object_storage` for LFS objects in `gitlab.rb`. Remember to restart GitLab afterwards.
-
-## Storage statistics
-
-You can see the total storage used for LFS objects on groups and projects
-in the administration area, as well as through the [groups](../../api/groups.md)
-and [projects APIs](../../api/projects.md).
-
-## Troubleshooting: `Google::Apis::TransmissionError: execution expired`
-
-If LFS integration is configred with Google Cloud Storage and background uploads (`background_upload: true` and `direct_upload: false`),
-Sidekiq workers may encouter this error. This is because the uploading timed out with very large files.
-LFS files up to 6Gb can be uploaded without any extra steps, otherwise you need to use the following workaround.
-
-```shell
-$ sudo gitlab-rails console # Login to rails console
-
-> # Set up timeouts. 20 minutes is enough to upload 30GB LFS files.
-> # These settings are only in effect for the same session, i.e. they are not effective for sidekiq workers.
-> ::Google::Apis::ClientOptions.default.open_timeout_sec = 1200
-> ::Google::Apis::ClientOptions.default.read_timeout_sec = 1200
-> ::Google::Apis::ClientOptions.default.send_timeout_sec = 1200
-
-> # Upload LFS files manually. This process does not use sidekiq at all.
-> LfsObject.where(file_store: [nil, 1]).find_each do |lfs_object|
-> lfs_object.file.migrate!(ObjectStorage::Store::REMOTE) if lfs_object.file.file.exists?
-> end
-```
-
-See more information in [!19581](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/19581)
-
-## Known limitations
-
-- Support for removing unreferenced LFS objects was added in 8.14 onwards.
-- LFS authentications via SSH was added with GitLab 8.12.
-- Only compatible with the Git LFS client versions 1.1.0 and up, or 1.0.2.
-- The storage statistics currently count each LFS object multiple times for
- every project linking to it.
-
-[reconfigure gitlab]: ../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure "How to reconfigure Omnibus GitLab"
-[restart gitlab]: ../../administration/restart_gitlab.md#installations-from-source "How to restart GitLab"
-[eep]: https://about.gitlab.com/pricing/ "GitLab Premium"
-[ee-2760]: https://gitlab.com/gitlab-org/gitlab/merge_requests/2760
+This document was moved to [another location](../../administration/lfs/lfs_administration.md).
diff --git a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
index f747a7b5196..56e2f72284a 100644
--- a/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
+++ b/doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
@@ -1,262 +1,5 @@
-# Git LFS
+---
+redirect_to: '../../administration/lfs/manage_large_binaries_with_git_lfs.md'
+---
-Managing large files such as audio, video and graphics files has always been one
-of the shortcomings of Git. The general recommendation is to not have Git repositories
-larger than 1GB to preserve performance.
-
-![Git LFS tracking status](img/lfs-icon.png)
-
-An LFS icon is shown on files tracked by Git LFS to denote if a file is stored
-as a blob or as an LFS pointer.
-
-## How it works
-
-Git LFS client talks with the GitLab server over HTTPS. It uses HTTP Basic Authentication
-to authorize client requests. Once the request is authorized, Git LFS client receives
-instructions from where to fetch or where to push the large file.
-
-## GitLab server configuration
-
-Documentation for GitLab instance administrators is under [LFS administration doc](lfs_administration.md).
-
-## Requirements
-
-- Git LFS is supported in GitLab starting with version 8.2
-- Git LFS must be enabled under project settings
-- [Git LFS client](https://git-lfs.github.com) version 1.0.1 and up
-
-## Known limitations
-
-- Git LFS v1 original API is not supported since it was deprecated early in LFS
- development
-- When SSH is set as a remote, Git LFS objects still go through HTTPS
-- Any Git LFS request will ask for HTTPS credentials to be provided so a good Git
- credentials store is recommended
-- Git LFS always assumes HTTPS so if you have GitLab server on HTTP you will have
- to add the URL to Git config manually (see [troubleshooting](#troubleshooting))
-
-NOTE: **Note:**
-With 8.12 GitLab added LFS support to SSH. The Git LFS communication
-still goes over HTTP, but now the SSH client passes the correct credentials
-to the Git LFS client, so no action is required by the user.
-
-## Using Git LFS
-
-Lets take a look at the workflow when you need to check large files into your Git
-repository with Git LFS. For example, if you want to upload a very large file and
-check it into your Git repository:
-
-```bash
-git clone git@gitlab.example.com:group/project.git
-git lfs install # initialize the Git LFS project
-git lfs track "*.iso" # select the file extensions that you want to treat as large files
-```
-
-Once a certain file extension is marked for tracking as a LFS object you can use
-Git as usual without having to redo the command to track a file with the same extension:
-
-```bash
-cp ~/tmp/debian.iso ./ # copy a large file into the current directory
-git add . # add the large file to the project
-git commit -am "Added Debian iso" # commit the file meta data
-git push origin master # sync the git repo and large file to the GitLab server
-```
-
-**Make sure** that `.gitattributes` is tracked by Git. Otherwise Git
-LFS will not be working properly for people cloning the project:
-
-```bash
-git add .gitattributes
-```
-
-Cloning the repository works the same as before. Git automatically detects the
-LFS-tracked files and clones them via HTTP. If you performed the `git clone`
-command with a SSH URL, you have to enter your GitLab credentials for HTTP
-authentication.
-
-```bash
-git clone git@gitlab.example.com:group/project.git
-```
-
-If you already cloned the repository and you want to get the latest LFS object
-that are on the remote repository, eg. for a branch from origin:
-
-```bash
-git lfs fetch origin master
-```
-
-### Migrate an existing repo to Git LFS
-
-Read the documentation on how to [migrate an existing Git repo with Git LFS](../../topics/git/migrate_to_git_lfs/index.md).
-
-## File Locking
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/35856) in GitLab 10.5.
-
-The first thing to do before using File Locking is to tell Git LFS which
-kind of files are lockable. The following command will store PNG files
-in LFS and flag them as lockable:
-
-```bash
-git lfs track "*.png" --lockable
-```
-
-After executing the above command a file named `.gitattributes` will be
-created or updated with the following content:
-
-```bash
-*.png filter=lfs diff=lfs merge=lfs -text lockable
-```
-
-You can also register a file type as lockable without using LFS
-(In order to be able to lock/unlock a file you need a remote server that implements the LFS File Locking API),
-in order to do that you can edit the `.gitattributes` file manually:
-
-```bash
-*.pdf lockable
-```
-
-After a file type has been registered as lockable, Git LFS will make
-them readonly on the file system automatically. This means you will
-need to lock the file before editing it.
-
-### Managing Locked Files
-
-Once you're ready to edit your file you need to lock it first:
-
-```bash
-git lfs lock images/banner.png
-Locked images/banner.png
-```
-
-This will register the file as locked in your name on the server:
-
-```bash
-git lfs locks
-images/banner.png joe ID:123
-```
-
-Once you have pushed your changes, you can unlock the file so others can
-also edit it:
-
-```bash
-git lfs unlock images/banner.png
-```
-
-You can also unlock by id:
-
-```bash
-git lfs unlock --id=123
-```
-
-If for some reason you need to unlock a file that was not locked by you,
-you can use the `--force` flag as long as you have a `maintainer` access on
-the project:
-
-```bash
-git lfs unlock --id=123 --force
-```
-
-## Troubleshooting
-
-### error: Repository or object not found
-
-There are a couple of reasons why this error can occur:
-
-- You don't have permissions to access certain LFS object
-
-Check if you have permissions to push to the project or fetch from the project.
-
-- Project is not allowed to access the LFS object
-
-LFS object you are trying to push to the project or fetch from the project is not
-available to the project anymore. Probably the object was removed from the server.
-
-- Local Git repository is using deprecated LFS API
-
-### Invalid status for `<url>` : 501
-
-Git LFS will log the failures into a log file.
-To view this log file, while in project directory:
-
-```bash
-git lfs logs last
-```
-
-If the status `error 501` is shown, it is because:
-
-- Git LFS is not enabled in project settings. Check your project settings and
- enable Git LFS.
-
-- Git LFS support is not enabled on the GitLab server. Check with your GitLab
- administrator why Git LFS is not enabled on the server. See
- [LFS administration documentation](lfs_administration.md) for instructions
- on how to enable LFS support.
-
-- Git LFS client version is not supported by GitLab server. Check your Git LFS
- version with `git lfs version`. Check the Git config of the project for traces
- of deprecated API with `git lfs -l`. If `batch = false` is set in the config,
- remove the line and try to update your Git LFS client. Only version 1.0.1 and
- newer are supported.
-
-### getsockopt: connection refused
-
-If you push a LFS object to a project and you receive an error similar to:
-`Post <URL>/info/lfs/objects/batch: dial tcp IP: getsockopt: connection refused`,
-the LFS client is trying to reach GitLab through HTTPS. However, your GitLab
-instance is being served on HTTP.
-
-This behaviour is caused by Git LFS using HTTPS connections by default when a
-`lfsurl` is not set in the Git config.
-
-To prevent this from happening, set the lfs url in project Git config:
-
-```bash
-git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs"
-```
-
-### Credentials are always required when pushing an object
-
-NOTE: **Note:**
-With 8.12 GitLab added LFS support to SSH. The Git LFS communication
-still goes over HTTP, but now the SSH client passes the correct credentials
-to the Git LFS client, so no action is required by the user.
-
-Given that Git LFS uses HTTP Basic Authentication to authenticate the user pushing
-the LFS object on every push for every object, user HTTPS credentials are required.
-
-By default, Git has support for remembering the credentials for each repository
-you use. This is described in [Git credentials man pages](https://git-scm.com/docs/gitcredentials).
-
-For example, you can tell Git to remember the password for a period of time in
-which you expect to push the objects:
-
-```bash
-git config --global credential.helper 'cache --timeout=3600'
-```
-
-This will remember the credentials for an hour after which Git operations will
-require re-authentication.
-
-If you are using OS X you can use `osxkeychain` to store and encrypt your credentials.
-For Windows, you can use `wincred` or Microsoft's [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases).
-
-More details about various methods of storing the user credentials can be found
-on [Git Credential Storage documentation](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage).
-
-### LFS objects are missing on push
-
-GitLab checks files to detect LFS pointers on push. If LFS pointers are detected, GitLab tries to verify that those files already exist in LFS on GitLab.
-
-Verify that LFS in installed locally and consider a manual push with `git lfs push --all`.
-
-If you are storing LFS files outside of GitLab you can disable LFS on the project by setting `lfs_enabled: false` with the [projects API](../../api/projects.md#edit-project).
-
-### Hosting LFS objects externally
-
-It is possible to host LFS objects externally by setting a custom LFS url with `git config -f .lfsconfig lfs.url https://example.com/<project>.git/info/lfs`.
-
-You might choose to do this if you are using an appliance like a Sonatype Nexus to store LFS data. If you choose to use an external LFS store,
-GitLab will not be able to verify LFS objects which means that pushes will fail if you have GitLab LFS support enabled.
-
-To stop push failure, LFS support can be disabled in the [Project settings](../../user/project/settings/index.md). This means you will lose GitLab LFS value-adds (Verifying LFS objects, UI integration for LFS).
+This document was moved to [another location](../../administration/lfs/manage_large_binaries_with_git_lfs.md).
diff --git a/doc/workflow/lfs/migrate_from_git_annex_to_git_lfs.md b/doc/workflow/lfs/migrate_from_git_annex_to_git_lfs.md
index 8f24929c9dc..997ef8938a6 100644
--- a/doc/workflow/lfs/migrate_from_git_annex_to_git_lfs.md
+++ b/doc/workflow/lfs/migrate_from_git_annex_to_git_lfs.md
@@ -1,254 +1,5 @@
-# Migration guide from Git Annex to Git LFS
-
->**Note:**
-Git Annex support [has been removed][issue-remove-annex] in GitLab Enterprise
-Edition 9.0 (2017/03/22).
-
-Both [Git Annex][] and [Git LFS][] are tools to manage large files in Git.
-
-## History
-
-Git Annex [was introduced in GitLab Enterprise Edition 7.8][post-3], at a time
-where Git LFS didn't yet exist. A few months later, GitLab brought support for
-Git LFS in [GitLab 8.2][post-2] and is available for both Community and
-Enterprise editions.
-
-## Differences between Git Annex and Git LFS
-
-Some items below are general differences between the two protocols and some are
-ones that GitLab developed.
-
-- Git Annex works only through SSH, whereas Git LFS works both with SSH and HTTPS
- (SSH support was added in GitLab 8.12).
-- Annex files are stored in a sub-directory of the normal repositories, whereas
- LFS files are stored outside of the repositories in a place you can define.
-- Git Annex requires a more complex setup, but has much more options than Git
- LFS. You can compare the commands each one offers by running `man git-annex`
- and `man git-lfs`.
-- Annex files cannot be browsed directly in GitLab's interface, whereas LFS
- files can.
-
-## Migration steps
-
->**Note:**
-Since Git Annex files are stored in a sub-directory of the normal repositories
-(`.git/annex/objects`) and LFS files are stored outside of the repositories,
-they are not compatible as they are using a different scheme. Therefore, the
-migration has to be done manually per repository.
-
-There are basically two steps you need to take in order to migrate from Git
-Annex to Git LFS.
-
-### TL; DR
-
-If you know what you are doing and want to skip the reading, this is what you
-need to do (we assume you have [git-annex enabled](../git_annex.md#using-gitlab-git-annex) in your
-repository and that you have made backups in case something goes wrong).
-Fire up a terminal, navigate to your Git repository and:
-
-1. Disable `git-annex`:
-
- ```bash
- git annex sync --content
- git annex direct
- git annex uninit
- git annex indirect
- ```
-
-1. Enable `git-lfs`:
-
- ```
- git lfs install
- git lfs track <files>
- git add .
- git commit -m "commit message"
- git push
- ```
-
-### Disabling Git Annex in your repo
-
-Before changing anything, make sure you have a backup of your repository first.
-There are a couple of ways to do that, but you can simply clone it to another
-local path and maybe push it to GitLab if you want a remote backup as well.
-Here you'll find a guide on
-[how to back up a **git-annex** repository to an external hard drive][bkp-ext-drive].
-
-Since Annex files are stored as objects with symlinks and cannot be directly
-modified, we need to first remove those symlinks.
-
-NOTE: **Note:**
-Make sure the you read about the [`direct` mode][annex-direct] as it contains
-useful information that may fit in your use case. Note that `annex direct` is
-deprecated in Git Annex version 6, so you may need to upgrade your repository
-if the server also has Git Annex 6 installed. Read more in the
-[Git Annex troubleshooting tips](../git_annex.md#troubleshooting-tips) section.
-
-1. Backup your repository
-
- ```bash
- cd repository
- git annex sync --content
- cd ..
- git clone repository repository-backup
- cd repository-backup
- git annex get
- cd ..
- ```
-
-1. Use `annex direct`:
-
- ```bash
- cd repository
- git annex direct
- ```
-
- The output should be similar to this:
-
- ```bash
- commit
- On branch master
- Your branch is up-to-date with 'origin/master'.
- nothing to commit, working tree clean
- ok
- direct debian.iso ok
- direct ok
- ```
-
-1. Disable Git Annex with [`annex uninit`][uninit]:
-
- ```bash
- git annex uninit
- ```
-
- The output should be similar to this:
-
- ```bash
- unannex debian.iso ok
- Deleted branch git-annex (was 2534d2c).
- ```
-
- This will `unannex` every file in the repository, leaving the original files.
-
-1. Switch back to `indirect` mode:
-
- ```bash
- git annex indirect
- ```
-
- The output should be similar to this:
-
- ```bash
- (merging origin/git-annex into git-annex...)
- (recording state in git...)
- commit (recording state in git...)
-
- ok
- (recording state in git...)
- [master fac3194] commit before switching to indirect mode
- 1 file changed, 1 deletion(-)
- delete mode 120000 alpine-virt-3.4.4-x86_64.iso
- ok
- indirect ok
- ok
- ```
-
+---
+redirect_to: '../../administration/lfs/migrate_from_git_annex_to_git_lfs.md'
---
-At this point, you have two options. Either add, commit and push the files
-directly back to GitLab or switch to Git LFS. We will tackle the LFS switch in
-the next section.
-
-### Enabling Git LFS in your repo
-
-Git LFS is enabled by default on all GitLab products (GitLab CE, GitLab EE,
-GitLab.com), therefore, you don't need to do anything server-side.
-
-1. First, make sure you have `git-lfs` installed locally:
-
- ```bash
- git lfs help
- ```
-
- If the terminal doesn't prompt you with a full response on `git-lfs` commands,
- [install the Git LFS client][install-lfs] first.
-
-1. Inside the repo, run the following command to initiate LFS:
-
- ```bash
- git lfs install
- ```
-
-1. Enable `git-lfs` for the group of files you want to track. You
- can track specific files, all files containing the same extension, or an
- entire directory:
-
- ```bash
- git lfs track images/01.png # per file
- git lfs track **/*.png # per extension
- git lfs track images/ # per directory
- ```
-
- Once you do that, run `git status` and you'll see `.gitattributes` added
- to your repo. It collects all file patterns that you chose to track via
- `git-lfs`.
-
-1. Add the files, commit and push them to GitLab:
-
- ```bash
- git add .
- git commit -m "commit message"
- git push
- ```
-
- If your remote is set up with HTTP, you will be asked to enter your login
- credentials. If you have [2FA enabled](../../user/profile/account/two_factor_authentication.md), make sure to use a
- [personal access token](../../user/profile/account/two_factor_authentication.md#personal-access-tokens)
- instead of your password.
-
-## Removing the Git Annex branches
-
-After the migration finishes successfully, you can remove all `git-annex`
-related branches from your repository.
-
-On GitLab, navigate to your project's **Repository ➔ Branches** and delete all
-branches created by Git Annex: `git-annex`, and all under `synced/`.
-
-![repository branches](images/git-annex-branches.png)
-
-You can also do this on the command line with:
-
-```bash
-git branch -d synced/master
-git branch -d synced/git-annex
-git push origin :synced/master
-git push origin :synced/git-annex
-git push origin :git-annex
-git remote prune origin
-```
-
-If there are still some Annex objects inside your repository (`.git/annex/`)
-or references inside `.git/config`, run `annex uninit` again:
-
-```bash
-git annex uninit
-```
-
-## Further Reading
-
-- (Blog Post) [Getting Started with Git FLS][post-1]
-- (Blog Post) [Announcing LFS Support in GitLab][post-2]
-- (Blog Post) [GitLab Annex Solves the Problem of Versioning Large Binaries with Git][post-3]
-- (GitLab Docs) [Git Annex](../git_annex.md)
-- (GitLab Docs) [Git LFS](manage_large_binaries_with_git_lfs.md)
-
-[annex-direct]: https://git-annex.branchable.com/direct_mode/
-[bkp-ext-drive]: https://www.thomas-krenn.com/en/wiki/Git-annex_Repository_on_an_External_Hard_Drive
-[Git Annex]: http://git-annex.branchable.com/
-[Git LFS]: https://git-lfs.github.com/
-[install-lfs]: https://git-lfs.github.com/
-[issue-remove-annex]: https://gitlab.com/gitlab-org/gitlab/issues/1648
-[lfs-track]: https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/#tracking-files-with-lfs
-[post-1]: https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/
-[post-2]: https://about.gitlab.com/blog/2015/11/23/announcing-git-lfs-support-in-gitlab/
-[post-3]: https://about.gitlab.com/blog/2015/02/17/gitlab-annex-solves-the-problem-of-versioning-large-binaries-with-git/
-[uninit]: https://git-annex.branchable.com/git-annex-uninit/
+This document was moved to [another location](../../administration/lfs/migrate_from_git_annex_to_git_lfs.md).
diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md
index 814accf3670..23f96360484 100644
--- a/doc/workflow/notifications.md
+++ b/doc/workflow/notifications.md
@@ -1,172 +1,5 @@
-# GitLab Notification Emails
+---
+redirect_to: '../user/profile/notifications.md'
+---
-GitLab has a notification system in place to notify a user of events that are important for the workflow.
-
-## Notification settings
-
-You can find notification settings under the user profile.
-
-![notification settings](img/notification_global_settings.png)
-
-Notification settings are divided into three groups:
-
-- Global settings
-- Group settings
-- Project settings
-
-Each of these settings have levels of notification:
-
-- Global: For groups and projects, notifications as per global settings.
-- Watch: Receive notifications for any activity.
-- Participate: Receive notifications for threads you have participated in.
-- On Mention: Receive notifications when `@mentioned` in comments.
-- Disabled: Turns off notifications.
-- Custom: Receive notifications for custom selected events.
-
-> Introduced in GitLab 12.0
-
-You can also select an email address to receive notifications for each group you belong to.
-
-### Global Settings
-
-Global settings are at the bottom of the hierarchy.
-Any setting set here will be overridden by a setting at the group or a project level.
-
-Group or Project settings can use `global` notification setting which will then use
-anything that is set at Global Settings.
-
-### Group Settings
-
-![notification settings](img/notification_group_settings.png)
-
-Group settings are taking precedence over Global Settings but are on a level below Project or Subgroup settings:
-
-```
-Group < Subgroup < Project
-```
-
-This means that you can set a different level of notifications per group while still being able
-to have a finer level setting per project or subgroup.
-Organization like this is suitable for users that belong to different groups but don't have the
-same need for being notified for every group they are member of.
-These settings can be configured on group page under the name of the group. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown.
-
-The group owner can disable email notifications for a group, which includes
-its subgroups and projects. If this is the case, you will not receive any corresponding notifications,
-and the notification button will be disabled with an explanatory tooltip.
-
-### Project Settings
-
-![notification settings](img/notification_project_settings.png)
-
-Project settings are at the top level and any setting placed at this level will take precedence of any
-other setting.
-This is suitable for users that have different needs for notifications per project basis.
-These settings can be configured on project page under the name of the project. It will be the dropdown with the bell icon. They can also be configured on the user profile notifications dropdown.
-
-The project owner (or its group owner) can disable email notifications for the project.
-If this is the case, you will not receive any corresponding notifications, and the notification
-button will be disabled with an explanatory tooltip.
-
-## Notification events
-
-Below is the table of events users can be notified of:
-
-| Event | Sent to | Settings level |
-|------------------------------|---------------------|------------------------------|
-| New SSH key added | User | Security email, always sent. |
-| New email added | User | Security email, always sent. |
-| Email changed | User | Security email, always sent. |
-| Password changed | User | Security email, always sent. |
-| New user created | User | Sent on user creation, except for OmniAuth (LDAP)|
-| User added to project | User | Sent when user is added to project |
-| Project access level changed | User | Sent when user project access level is changed |
-| User added to group | User | Sent when user is added to group |
-| Group access level changed | User | Sent when user group access level is changed |
-| Project moved | Project members (1) | (1) not disabled |
-| New release | Project members | Custom notification |
-
-### Issue / Epics / Merge request events
-
-In most of the below cases, the notification will be sent to:
-
-- Participants:
- - the author and assignee of the issue/merge request
- - authors of comments on the issue/merge request
- - anyone mentioned by `@username` in the title or description of the issue, merge request or epic **(ULTIMATE)**
- - anyone with notification level "Participating" or higher that is mentioned by `@username`
- in any of the comments on the issue, merge request, or epic **(ULTIMATE)**
-- Watchers: users with notification level "Watch"
-- Subscribers: anyone who manually subscribed to the issue, merge request, or epic **(ULTIMATE)**
-- Custom: Users with notification level "custom" who turned on notifications for any of the events present in the table below
-
-| Event | Sent to |
-|------------------------|---------|
-| New issue | |
-| Close issue | |
-| Reassign issue | The above, plus the old assignee |
-| Reopen issue | |
-| Due issue | Participants and Custom notification level with this event selected |
-| Change milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected |
-| Remove milestone issue | Subscribers, participants mentioned, and Custom notification level with this event selected |
-| New merge request | |
-| Push to merge request | Participants and Custom notification level with this event selected |
-| Reassign merge request | The above, plus the old assignee |
-| Close merge request | |
-| Reopen merge request | |
-| Merge merge request | |
-| Change milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected |
-| Remove milestone merge request | Subscribers, participants mentioned, and Custom notification level with this event selected |
-| New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher |
-| Failed pipeline | The author of the pipeline |
-| Successful pipeline | The author of the pipeline, if they have the custom notification setting for successful pipelines set |
-| New epic **(ULTIMATE)** | |
-| Close epic **(ULTIMATE)** | |
-| Reopen epic **(ULTIMATE)** | |
-
-In addition, if the title or description of an Issue or Merge Request is
-changed, notifications will be sent to any **new** mentions by `@username` as
-if they had been mentioned in the original text.
-
-You won't receive notifications for Issues, Merge Requests or Milestones created
-by yourself (except when an issue is due). You will only receive automatic
-notifications when somebody else comments or adds changes to the ones that
-you've created or mentions you.
-
-If an open merge request becomes unmergeable due to conflict, its author will be notified about the cause.
-If a user has also set the merge request to automatically merge once pipeline succeeds,
-then that user will also be notified.
-
-### Email Headers
-
-Notification emails include headers that provide extra content about the notification received:
-
-| Header | Description |
-|-----------------------------|-------------------------------------------------------------------------|
-| X-GitLab-Project | The name of the project the notification belongs to |
-| X-GitLab-Project-Id | The ID of the project |
-| X-GitLab-Project-Path | The path of the project |
-| X-GitLab-(Resource)-ID | The ID of the resource the notification is for, where resource is `Issue`, `MergeRequest`, `Commit`, etc|
-| X-GitLab-Discussion-ID | Only in comment emails, the ID of the thread the comment is from |
-| X-GitLab-Pipeline-Id | Only in pipeline emails, the ID of the pipeline the notification is for |
-| X-GitLab-Reply-Key | A unique token to support reply by email |
-| X-GitLab-NotificationReason | The reason for being notified. "mentioned", "assigned", etc |
-| List-Id | The path of the project in a RFC 2919 mailing list identifier useful for email organization, for example, with Gmail filters |
-
-#### X-GitLab-NotificationReason
-
-This header holds the reason for the notification to have been sent out,
-where reason can be `mentioned`, `assigned`, `own_activity`, etc.
-Only one reason is sent out according to its priority:
-
-- `own_activity`
-- `assigned`
-- `mentioned`
-
-The reason in this header will also be shown in the footer of the notification email. For example an email with the
-reason `assigned` will have this sentence in the footer:
-`"You are receiving this email because you have been assigned an item on {configured GitLab hostname}"`
-
-NOTE: **Note:**
-Only reasons listed above have been implemented so far.
-Further implementation is [being discussed](https://gitlab.com/gitlab-org/gitlab-foss/issues/42062).
+This document was moved to [another location](../user/profile/notifications.md).
diff --git a/doc/workflow/releases.md b/doc/workflow/releases.md
index 1fd63a556c6..f3ba61f6a5c 100644
--- a/doc/workflow/releases.md
+++ b/doc/workflow/releases.md
@@ -1,22 +1,5 @@
-# Releases
+---
+redirect_to: '../user/project/releases/index.md#add-release-notes-to-git-tags'
+---
-NOTE: In GitLab 11.7, we introduced the full fledged [Releases](../user/project/releases/index.md)
-feature. You can still create release notes on this page, but the new method is preferred.
-
-You can add release notes to any Git tag using the notes feature. Release notes
-behave like any other markdown form in GitLab so you can write text and
-drag-n-drop files to it. Release notes are stored in GitLab's database.
-
-There are several ways to add release notes:
-
-- In the interface, when you create a new Git tag
-- In the interface, by adding a note to an existing Git tag
-- Using the GitLab API
-
-## New tag page with release notes text area
-
-![new_tag](releases/new_tag.png)
-
-## Tags page with button to add or edit release notes for existing Git tag
-
-![tags](releases/tags.png)
+This document was moved to [another location](../user/project/releases/index.md#add-release-notes-to-git-tags).
diff --git a/doc/workflow/repository_mirroring.md b/doc/workflow/repository_mirroring.md
index 6d1a5913789..dc77f4f47af 100644
--- a/doc/workflow/repository_mirroring.md
+++ b/doc/workflow/repository_mirroring.md
@@ -1,426 +1,5 @@
-# Repository mirroring
-
-Repository mirroring allows for mirroring of repositories to and from external sources. It can be
-used to mirror branches, tags, and commits between repositories.
-
-A repository mirror at GitLab will be updated automatically. You can also manually trigger an update
-at most once every 5 minutes.
-
-## Overview
-
-Repository mirroring is useful when you want to use a repository outside of GitLab.
-
-There are two kinds of repository mirroring supported by GitLab:
-
-- Push: for mirroring a GitLab repository to another location.
-- Pull: for mirroring a repository from another location to GitLab. **(STARTER)**
-
-When the mirror repository is updated, all new branches, tags, and commits will be visible in the
-project's activity feed.
-
-Users with at least [developer access](../user/permissions.md) to the project can also force an
-immediate update, unless:
-
-- The mirror is already being updated.
-- 5 minutes haven't elapsed since its last update.
-
-## Use cases
-
-The following are some possible use cases for repository mirroring:
-
-- You migrated to GitLab but still need to keep your project in another source. In that case, you
- can simply set it up to mirror to GitLab (pull) and all the essential history of commits, tags,
- and branches will be available in your GitLab instance. **(STARTER)**
-- You have old projects in another source that you don't use actively anymore, but don't want to
- remove for archiving purposes. In that case, you can create a push mirror so that your active
- GitLab repository can push its changes to the old location.
-
-## Pushing to a remote repository **(CORE)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/249) in GitLab Enterprise Edition 8.7.
-> - [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18715) in 10.8.
-
-For an existing project, you can set up push mirroring as follows:
-
-1. Navigate to your project's **Settings > Repository** and expand the **Mirroring repositories** section.
-1. Enter a repository URL.
-1. Select **Push** from the **Mirror direction** dropdown.
-1. Select an authentication method from the **Authentication method** dropdown, if necessary.
-1. Check the **Only mirror protected branches** box, if necessary.
-1. Click the **Mirror repository** button to save the configuration.
-
-![Repository mirroring push settings screen](img/repository_mirroring_push_settings.png)
-
-When push mirroring is enabled, only push commits directly to the mirrored repository to prevent the
-mirror diverging. All changes will end up in the mirrored repository whenever:
-
-- Commits are pushed to GitLab.
-- A [forced update](#forcing-an-update-core) is initiated.
-
-Changes pushed to files in the repository are automatically pushed to the remote mirror at least:
-
-- Within five minutes of being received.
-- Within one minute if **Only mirror protected branches** is enabled.
-
-In the case of a diverged branch, you will see an error indicated at the **Mirroring repositories**
-section.
-
-### Push only protected branches **(CORE)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3350) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
-> - [Moved to GitLab Core](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/18715) in 10.8.
-
-You can choose to only push your protected branches from GitLab to your remote repository.
-
-To use this option, check the **Only mirror protected branches** box when creating a repository
-mirror.
-
-## Setting up a push mirror from GitLab to GitHub **(CORE)**
-
-To set up a mirror from GitLab to GitHub, you need to follow these steps:
-
-1. Create a [GitHub personal access token](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) with the `public_repo` box checked.
-1. Fill in the **Git repository URL** field using this format: `https://<your_github_username>@github.com/<your_github_group>/<your_github_project>.git`.
-1. Fill in **Password** field with your GitHub personal access token.
-1. Click the **Mirror repository** button.
-
-The mirrored repository will be listed. For example, `https://*****:*****@github.com/<your_github_group>/<your_github_project>.git`.
-
-The repository will push soon. To force a push, click the appropriate button.
-
-## Setting up a push mirror to another GitLab instance with 2FA activated
-
-1. On the destination GitLab instance, create a [personal access token](../user/profile/personal_access_tokens.md) with `API` scope.
-1. On the source GitLab instance:
- 1. Fill in the **Git repository URL** field using this format: `https://oauth2@<destination host>/<your_gitlab_group_or_name>/<your_gitlab_project>.git`.
- 1. Fill in **Password** field with the GitLab personal access token created on the destination GitLab instance.
- 1. Click the **Mirror repository** button.
-
-## Pulling from a remote repository **(STARTER)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/51) in GitLab Enterprise Edition 8.2.
-> - [Added Git LFS support](https://gitlab.com/gitlab-org/gitlab/issues/10871) in [GitLab Starter](https://about.gitlab.com/pricing/) 11.11.
-
-NOTE: **Note:** This feature [is available for free](https://gitlab.com/gitlab-org/gitlab/issues/10361) to
-GitLab.com users until March 22nd, 2020.
-
-You can set up a repository to automatically have its branches, tags, and commits updated from an
-upstream repository.
-
-This is useful when a repository you're interested in is located on a different server, and you want
-to be able to browse its content and its activity using the familiar GitLab interface.
-
-To configure mirror pulling for an existing project:
-
-1. Navigate to your project's **Settings > Repository** and expand the **Mirroring repositories**
- section.
-1. Enter a repository URL.
-1. Select **Pull** from the **Mirror direction** dropdown.
-1. Select an authentication method from the **Authentication method** dropdown, if necessary.
-1. If necessary, check the following boxes:
- - **Overwrite diverged branches**.
- - **Trigger pipelines for mirror updates**.
- - **Only mirror protected branches**.
-1. Click the **Mirror repository** button to save the configuration.
-
-![Repository mirroring pull settings screen - upper part](img/repository_mirroring_pull_settings_upper.png)
-
+---
+redirect_to: '../user/project/repository/repository_mirroring.md'
---
-![Repository mirroring pull settings screen - lower part](img/repository_mirroring_pull_settings_lower.png)
-
-Because GitLab is now set to pull changes from the upstream repository, you should not push commits
-directly to the repository on GitLab. Instead, any commits should be pushed to the upstream repository.
-Changes pushed to the upstream repository will be pulled into the GitLab repository, either:
-
-- Automatically within a certain period of time.
-- When a [forced update](#forcing-an-update-core) is initiated.
-
-CAUTION: **Caution:**
-If you do manually update a branch in the GitLab repository, the branch will become diverged from
-upstream and GitLab will no longer automatically update this branch to prevent any changes from being lost.
-
-### How it works
-
-Once the pull mirroring feature has been enabled for a repository, the repository is added to a queue.
-
-Once per minute, a Sidekiq cron job schedules repository mirrors to update, based on:
-
-- The capacity available. This is determined by Sidekiq settings. For GitLab.com, see [GitLab.com Sidekiq settings](../user/gitlab_com/index.md#sidekiq).
-- The number of repository mirrors already in the queue that are due to be updated. Being due depends on when the repository mirror was last updated and how many times it's been retried.
-
-Repository mirrors are updated as Sidekiq becomes available to process them. If the process of updating the repository mirror:
-
-- Succeeds, an update will be enqueued again with at least a 30 minute wait.
-- Fails (for example, a branch diverged from upstream), it will be attempted again later. Mirrors can fail
- up to 14 times before they will not be enqueued for update again.
-
-### SSH authentication
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/2551) for Pull mirroring in [GitLab Starter](https://about.gitlab.com/pricing/) 9.5.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/22982) for Push mirroring in [GitLab Core](https://about.gitlab.com/pricing/) 11.6
-
-SSH authentication is mutual:
-
-- You have to prove to the server that you're allowed to access the repository.
-- The server also has to prove to *you* that it's who it claims to be.
-
-You provide your credentials as a password or public key. The server that the
-other repository resides on provides its credentials as a "host key", the
-fingerprint of which needs to be verified manually.
-
-If you're mirroring over SSH (that is, using an `ssh://` URL), you can authenticate using:
-
-- Password-based authentication, just as over HTTPS.
-- Public key authentication. This is often more secure than password authentication,
- especially when the other repository supports [Deploy Keys](../ssh/README.md#deploy-keys).
-
-To get started:
-
-1. Navigate to your project's **Settings > Repository** and expand the **Mirroring repositories** section.
-1. Enter an `ssh://` URL for mirroring.
-
-NOTE: **Note:**
-SCP-style URLs (that is, `git@example.com:group/project.git`) are not supported at this time.
-
-Entering the URL adds two buttons to the page:
-
-- **Detect host keys**.
-- **Input host keys manually**.
-
-If you click the:
-
-- **Detect host keys** button, GitLab will fetch the host keys from the server and display the fingerprints.
-- **Input host keys manually** button, a field is displayed where you can paste in host keys.
-
-Assuming you used the former, you now need to verify that the fingerprints are
-those you expect. GitLab.com and other code hosting sites publish their
-fingerprints in the open for you to check:
-
-- [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html#regions-fingerprints)
-- [Bitbucket](https://confluence.atlassian.com/bitbucket/ssh-keys-935365775.html)
-- [GitHub](https://help.github.com/en/articles/githubs-ssh-key-fingerprints)
-- [GitLab.com](../user/gitlab_com/index.md#ssh-host-keys-fingerprints)
-- [Launchpad](https://help.launchpad.net/SSHFingerprints)
-- [Savannah](http://savannah.gnu.org/maintenance/SshAccess/)
-- [SourceForge](https://sourceforge.net/p/forge/documentation/SSH%20Key%20Fingerprints/)
-
-Other providers will vary. If you're running self-managed GitLab, or otherwise
-have access to the server for the other repository, you can securely gather the
-key fingerprints:
-
-```sh
-$ cat /etc/ssh/ssh_host*pub | ssh-keygen -E md5 -l -f -
-256 MD5:f4:28:9f:23:99:15:21:1b:bf:ed:1f:8e:a0:76:b2:9d root@example.com (ECDSA)
-256 MD5:e6:eb:45:8a:3c:59:35:5f:e9:5b:80:12:be:7e:22:73 root@example.com (ED25519)
-2048 MD5:3f:72:be:3d:62:03:5c:62:83:e8:6e:14:34:3a:85:1d root@example.com (RSA)
-```
-
-NOTE: **Note:**
-You may need to exclude `-E md5` for some older versions of SSH.
-
-When mirroring the repository, GitLab will now check that at least one of the
-stored host keys matches before connecting. This can prevent malicious code from
-being injected into your mirror, or your password being stolen.
-
-### SSH public key authentication
-
-To use SSH public key authentication, you'll also need to choose that option
-from the **Authentication method** dropdown. When the mirror is created,
-GitLab generates a 4096-bit RSA key that can be copied by clicking the **Copy SSH public key** button.
-
-![Repository mirroring copy SSH public key to clipboard button](img/copy_ssh_public_key_button.png)
-
-You then need to add the public SSH key to the other repository's configuration:
-
-- If the other repository is hosted on GitLab, you should add the public SSH key
- as a [Deploy Key](../ssh/README.md#deploy-keys).
-- If the other repository is hosted elsewhere, you may need to add the key to
- your user's `authorized_keys` file. Paste the entire public SSH key into the
- file on its own line and save it.
-
-If you need to change the key at any time, you can remove and re-add the mirror
-to generate a new key. You'll have to update the other repository with the new
-key to keep the mirror running.
-
-### Overwrite diverged branches **(STARTER)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/4559) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.6.
-
-You can choose to always update your local branches with remote versions, even if they have
-diverged from the remote.
-
-CAUTION: **Caution:**
-For mirrored branches, enabling this option results in the loss of local changes.
-
-To use this option, check the **Overwrite diverged branches** box when creating a repository mirror.
-
-### Only mirror protected branches **(STARTER)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3326) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
-
-You can choose to pull mirror only the protected branches from your remote repository to GitLab.
-Non-protected branches are not mirrored and can diverge.
-
-To use this option, check the **Only mirror protected branches** box when creating a repository mirror.
-
-### Hard failure **(STARTER)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3117) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.2.
-
-Once the mirroring process is unsuccessfully retried 14 times in a row, it will get marked as hard
-failed. This will become visible in either the:
-
-- Project's main dashboard.
-- Pull mirror settings page.
-
-When a project is hard failed, it will no longer get picked up for mirroring. A user can resume the
-project mirroring again by [Forcing an update](#forcing-an-update-core).
-
-### Trigger update using API **(STARTER)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/3453) in [GitLab Starter](https://about.gitlab.com/pricing/) 10.3.
-
-Pull mirroring uses polling to detect new branches and commits added upstream, often minutes
-afterwards. If you notify GitLab by [API](../api/projects.md#start-the-pull-mirroring-process-for-a-project-starter),
-updates will be pulled immediately.
-
-For more information, see [Start the pull mirroring process for a Project](../api/projects.md#start-the-pull-mirroring-process-for-a-project-starter).
-
-## Forcing an update **(CORE)**
-
-While mirrors are scheduled to update automatically, you can always force an update by using the
-update button which is available on the **Mirroring repositories** section of the **Repository Settings** page.
-
-![Repository mirroring force update user interface](img/repository_mirroring_force_update.png)
-
-## Bidirectional mirroring **(STARTER)**
-
-CAUTION: **Caution:**
-Bidirectional mirroring may cause conflicts.
-
-If you configure a GitLab repository to both pull from, and push to, the same remote source, there
-is no guarantee that either repository will update correctly. If you set up a repository for
-bidirectional mirroring, you should prepare for the likely conflicts by deciding who will resolve
-them and how they will be resolved.
-
-Rewriting any mirrored commit on either remote will cause conflicts and mirroring to fail. This can
-be prevented by:
-
-- [Pulling only protected branches](#only-mirror-protected-branches-starter).
-- [Pushing only protected branches](#push-only-protected-branches-core).
-
-You should [protect the branches](../user/project/protected_branches.md) you wish to mirror on both
-remotes to prevent conflicts caused by rewriting history.
-
-Bidirectional mirroring also creates a race condition where commits made close together to the same
-branch causes conflicts. The race condition can be mitigated by reducing the mirroring delay by using
-a [Push event webhook](../user/project/integrations/webhooks.md#push-events) to trigger an immediate
-pull to GitLab. Push mirroring from GitLab is rate limited to once per minute when only push mirroring
-protected branches.
-
-### Preventing conflicts using a `pre-receive` hook
-
-CAUTION: **Warning:**
-The solution proposed will negatively impact the performance of
-Git push operations because they will be proxied to the upstream Git
-repository.
-
-A server-side `pre-receive` hook can be used to prevent the race condition
-described above by only accepting the push after first pushing the commit to
-the upstream Git repository. In this configuration one Git repository acts as
-the authoritative upstream, and the other as downstream. The `pre-receive` hook
-will be installed on the downstream repository.
-
-Read about [configuring custom Git hooks](../administration/custom_hooks.md) on the GitLab server.
-
-A sample `pre-receive` hook is provided below.
-
-```bash
-#!/usr/bin/env bash
-
-# --- Assume only one push mirror target
-# Push mirroring remotes are named `remote_mirror_<id>`, this finds the first remote and uses that.
-TARGET_REPO=$(git remote | grep -m 1 remote_mirror)
-
-proxy_push()
-{
- # --- Arguments
- OLDREV=$(git rev-parse $1)
- NEWREV=$(git rev-parse $2)
- REFNAME="$3"
-
- # --- Pattern of branches to proxy pushes
- whitelisted=$(expr "$branch" : "\(master\)")
-
- case "$refname" in
- refs/heads/*)
- branch=$(expr "$refname" : "refs/heads/\(.*\)")
-
- if [ "$whitelisted" = "$branch" ]; then
- error="$(git push --quiet $TARGET_REPO $NEWREV:$REFNAME 2>&1)"
- fail=$?
-
- if [ "$fail" != "0" ]; then
- echo >&2 ""
- echo >&2 " Error: updates were rejected by upstream server"
- echo >&2 " This is usually caused by another repository pushing changes"
- echo >&2 " to the same ref. You may want to first integrate remote changes"
- echo >&2 ""
- return
- fi
- fi
- ;;
- esac
-}
-
-# Allow dual mode: run from the command line just like the update hook, or
-# if no arguments are given then run as a hook script
-if [ -n "$1" -a -n "$2" -a -n "$3" ]; then
- # Output to the terminal in command line mode - if someone wanted to
- # resend an email; they could redirect the output to sendmail
- # themselves
- PAGER= proxy_push $2 $3 $1
-else
- # Push is proxied upstream one ref at a time. Because of this it is possible
- # for some refs to succeed, and others to fail. This will result in a failed
- # push.
- while read oldrev newrev refname
- do
- proxy_push $oldrev $newrev $refname
- done
-fi
-```
-
-### Mirroring with Perforce Helix via Git Fusion **(STARTER)**
-
-CAUTION: **Warning:**
-Bidirectional mirroring should not be used as a permanent configuration. Refer to
-[Migrating from Perforce Helix](../user/project/import/perforce.md) for alternative migration approaches.
-
-[Git Fusion](https://www.perforce.com/manuals/git-fusion/#Git-Fusion/section_avy_hyc_gl.html) provides a Git interface
-to [Perforce Helix](https://www.perforce.com/products) which can be used by GitLab to bidirectionally
-mirror projects with GitLab. This may be useful in some situations when migrating from Perforce Helix
-to GitLab where overlapping Perforce Helix workspaces cannot be migrated simultaneously to GitLab.
-
-If using mirroring with Perforce Helix, you should only mirror protected branches. Perforce Helix
-will reject any pushes that rewrite history. Only the fewest number of branches should be mirrored
-due to the performance limitations of Git Fusion.
-
-When configuring mirroring with Perforce Helix via Git Fusion, the following Git Fusion
-settings are recommended:
-
-- `change-pusher` should be disabled. Otherwise, every commit will be rewritten as being committed
- by the mirroring account, rather than being mapped to existing Perforce Helix users or the `unknown_git` user.
-- `unknown_git` user will be used as the commit author if the GitLab user does not exist in
- Perforce Helix.
-
-Read about [Git Fusion settings on Perforce.com](https://www.perforce.com/manuals/git-fusion/Content/Git-Fusion/section_vss_bdw_w3.html#section_zdp_zz1_3l).
-
-## Troubleshooting
-
-Should an error occur during a push, GitLab will display an "Error" highlight for that repository. Details on the error can then be seen by hovering over the highlight text.
-
-### 13:Received RST_STREAM with error code 2 with GitHub
-
-If you receive an "13:Received RST_STREAM with error code 2" while mirroring to a GitHub repository, your GitHub settings might be set to block pushes that expose your email address used in commits. Either set your email address on GitHub to be public, or disable the [Block command line pushes that expose my email](https://github.com/settings/emails) setting.
+This document was moved to [another location](../user/project/repository/repository_mirroring.md).
diff --git a/doc/workflow/shortcuts.md b/doc/workflow/shortcuts.md
index 2ec733182f8..4b35c61ec5e 100644
--- a/doc/workflow/shortcuts.md
+++ b/doc/workflow/shortcuts.md
@@ -1,134 +1,5 @@
---
-type: reference
+redirect_to: '../user/shortcuts.md'
---
-# GitLab keyboard shortcuts
-
-GitLab has many useful keyboard shortcuts to make it easier to access different features.
-You can see the quick reference sheet within GitLab itself with <kbd>Shift</kbd> + <kbd>?</kbd>.
-
-The [Global Shortcuts](#global-shortcuts) work from any area of GitLab, but you must
-be in specific pages for the other shortcuts to be available, as explained in each
-section below.
-
-## Global Shortcuts
-
-These shortcuts are available in most areas of GitLab
-
-| Keyboard Shortcut | Description |
-| ------------------------------- | ----------- |
-| <kbd>?</kbd> | Show/hide shortcut reference sheet. |
-| <kbd>Shift</kbd> + <kbd>p</kbd> | Go to your Projects page. |
-| <kbd>Shift</kbd> + <kbd>g</kbd> | Go to your Groups page. |
-| <kbd>Shift</kbd> + <kbd>a</kbd> | Go to your Activity page. |
-| <kbd>Shift</kbd> + <kbd>l</kbd> | Go to your Milestones page. |
-| <kbd>Shift</kbd> + <kbd>s</kbd> | Go to your Snippets page. |
-| <kbd>s</kbd> | Put cursor in the issues/merge requests search. |
-| <kbd>Shift</kbd> + <kbd>i</kbd> | Go to your Issues page. |
-| <kbd>Shift</kbd> + <kbd>m</kbd> | Go to your Merge requests page.|
-| <kbd>Shift</kbd> + <kbd>t</kbd> | Go to your To-Do List page. |
-| <kbd>p</kbd> + <kbd>b</kbd> | Show/hide the Performance Bar. |
-
-Additionally, the following shortcuts are available when editing text in text fields,
-for example comments, replies, or issue and merge request descriptions:
-
-| Keyboard Shortcut | Description |
-| ---------------------------------------------------------------------- | ----------- |
-| <kbd>↑</kbd> | Edit your last comment. You must be in a blank text field below a thread, and you must already have at least one comment in the thread. |
-| <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>p</kbd> | Toggle Markdown preview, when editing text in a text field that has **Write** and **Preview** tabs at the top. |
-
-## Project
-
-These shortcuts are available from any page within a project. You must type them
-relatively quickly to work, and they will take you to another page in the project.
-
-| Keyboard Shortcut | Description |
-| --------------------------- | ----------- |
-| <kbd>g</kbd> + <kbd>p</kbd> | Go to the project home page (**Project > Details**). |
-| <kbd>g</kbd> + <kbd>v</kbd> | Go to the project activity feed (**Project > Activity**). |
-| <kbd>g</kbd> + <kbd>r</kbd> | Go to the project releases list (**Project > Releases**). |
-| <kbd>g</kbd> + <kbd>f</kbd> | Go to the [project files](#project-files) list (**Repository > Files**). |
-| <kbd>t</kbd> | Go to the project file search page. (**Repository > Files**, click **Find Files**). |
-| <kbd>g</kbd> + <kbd>c</kbd> | Go to the project commits list (**Repository > Commits**). |
-| <kbd>g</kbd> + <kbd>n</kbd> | Go to the [repository graph](#repository-graph) page (**Repository > Graph**). |
-| <kbd>g</kbd> + <kbd>d</kbd> | Go to repository charts (**Repository > Charts**). |
-| <kbd>g</kbd> + <kbd>i</kbd> | Go to the project issues list (**Issues > List**). |
-| <kbd>i</kbd> | Go to the New Issue page (**Issues**, click **New Issue** ). |
-| <kbd>g</kbd> + <kbd>b</kbd> | Go to the project issue boards list (**Issues > Boards**). |
-| <kbd>g</kbd> + <kbd>m</kbd> | Go to the project merge requests list (**Merge Requests**). |
-| <kbd>g</kbd> + <kbd>j</kbd> | Go to the CI/CD jobs list (**CI/CD > Jobs**). |
-| <kbd>g</kbd> + <kbd>l</kbd> | Go to the project metrics (**Operations > Metrics**). |
-| <kbd>g</kbd> + <kbd>e</kbd> | Go to the project environments (**Operations > Environments**). |
-| <kbd>g</kbd> + <kbd>k</kbd> | Go to the project Kubernetes cluster integration page (**Operations > Kubernetes**). Note that you must have at least [`maintainer` permissions](../user/permissions.md) to access this page. |
-| <kbd>g</kbd> + <kbd>s</kbd> | Go to the project snippets list (**Snippets**). |
-| <kbd>g</kbd> + <kbd>w</kbd> | Go to the project wiki (**Wiki**), if enabled. |
-
-### Issues and Merge Requests
-
-These shortcuts are available when viewing issues and merge requests.
-
-| Keyboard Shortcut | Description |
-| ---------------------------- | ----------- |
-| <kbd>e</kbd> | Edit description. |
-| <kbd>a</kbd> | Change assignee. |
-| <kbd>m</kbd> | Change milestone. |
-| <kbd>l</kbd> | Change label. |
-| <kbd>r</kbd> | Start writing a comment. If any text is selected, it will be quoted in the comment. Can't be used to reply within a thread. |
-| <kbd>n</kbd> | Move to next unresolved discussion (Merge requests only). |
-| <kbd>p</kbd> | Move to previous unresolved discussion (Merge requests only). |
-| <kbd>]</kbd> or <kbd>j</kbd> | Move to next file (Merge requests only). |
-| <kbd>[</kbd> or <kbd>k</kbd> | Move to previous file (Merge requests only). |
-
-### Project Files
-
-These shortcuts are available when browsing the files in a project (navigate to
-**Repository** > **Files**):
-
-| Keyboard Shortcut | Description |
-| ----------------- | ----------- |
-| <kbd>↑</kbd> | Move selection up. |
-| <kbd>↓</kbd> | Move selection down. |
-| <kbd>enter</kbd> | Open selection. |
-| <kbd>esc</kbd> | Go back to file list screen (only while searching for files, **Repository > Files** then click on **Find File**). |
-| <kbd>y</kbd> | Go to file permalink (only while viewing a file). |
-
-### Web IDE
-
-These shortcuts are available when editing a file with the [Web IDE](../user/project/web_ide/index.md):
-
-| Keyboard Shortcut | Description |
-| ------------------------------------------------------- | ----------- |
-| <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> + <kbd>p</kbd> | Search for, and then open another file for editing. |
-| <kbd>⌘</kbd> (Mac) / <kbd>Ctrl</kbd> + <kbd>Enter</kbd> | Commit (when editing the commit message). |
-
-### Repository Graph
-
-These shortcuts are available when viewing the project [repository graph](../user/project/repository/index.md#repository-graph)
-page (navigate to **Repository > Graph**):
-
-| Keyboard Shortcut | Description |
-| ------------------------------------------------------------------ | ----------- |
-| <kbd>←</kbd> or <kbd>h</kbd> | Scroll left. |
-| <kbd>→</kbd> or <kbd>l</kbd> | Scroll right. |
-| <kbd>↑</kbd> or <kbd>k</kbd> | Scroll up. |
-| <kbd>↓</kbd> or <kbd>j</kbd> | Scroll down. |
-| <kbd>Shift</kbd> + <kbd>↑</kbd> or <kbd>Shift</kbd> + <kbd>k</kbd> | Scroll to top. |
-| <kbd>Shift</kbd> + <kbd>↓</kbd> or <kbd>Shift</kbd> + <kbd>j</kbd> | Scroll to bottom. |
-
-### Wiki pages
-
-This shortcut is available when viewing a [wiki page](../user/project/wiki/index.md):
-
-| Keyboard Shortcut | Description |
-| ----------------- | ----------- |
-| <kbd>e</kbd> | Edit wiki page. |
-
-## Epics **(ULTIMATE)**
-
-These shortcuts are available when viewing [Epics](../user/group/epics/index.md):
-
-| Keyboard Shortcut | Description |
-| ----------------- | ----------- |
-| <kbd>r</kbd> | Start writing a comment. If any text is selected, it will be quoted in the comment. Can't be used to reply within a thread. |
-| <kbd>e</kbd> | Edit description. |
-| <kbd>l</kbd> | Change label. |
+This document was moved to [another location](../user/shortcuts.md).
diff --git a/doc/workflow/time_tracking.md b/doc/workflow/time_tracking.md
index 3d2e1de24da..e109410e22d 100644
--- a/doc/workflow/time_tracking.md
+++ b/doc/workflow/time_tracking.md
@@ -1,91 +1,5 @@
---
-type: reference
+redirect_to: '../user/project/time_tracking.md'
---
-# Time Tracking
-
-> Introduced in GitLab 8.14.
-
-Time Tracking allows you to track estimates and time spent on issues and merge
-requests within GitLab.
-
-## Overview
-
-Time Tracking allows you to:
-
-- Record the time spent working on an issue or a merge request.
-- Add an estimate of the amount of time needed to complete an issue or a merge
- request.
-
-You don't have to indicate an estimate to enter the time spent, and vice versa.
-
-Data about time tracking is shown on the issue/merge request sidebar, as shown
-below.
-
-![Time tracking in the sidebar](time_tracking/img/time_tracking_sidebar_v8_16.png)
-
-## How to enter data
-
-Time Tracking uses two [quick actions](../user/project/quick_actions.md)
-that GitLab introduced with this new feature: `/spend` and `/estimate`.
-
-Quick actions can be used in the body of an issue or a merge request, but also
-in a comment in both an issue or a merge request.
-
-Below is an example of how you can use those new quick actions inside a comment.
-
-![Time tracking example in a comment](time_tracking/img/time_tracking_example_v12_2.png)
-
-Adding time entries (time spent or estimates) is limited to project members.
-
-### Estimates
-
-To enter an estimate, write `/estimate`, followed by the time. For example, if
-you need to enter an estimate of 3 days, 5 hours and 10 minutes, you would write
-`/estimate 3d 5h 10m`. Time units that we support are listed at the bottom of
-this help page.
-
-Every time you enter a new time estimate, any previous time estimates will be
-overridden by this new value. There should only be one valid estimate in an
-issue or a merge request.
-
-To remove an estimation entirely, use `/remove_estimate`.
-
-### Time spent
-
-To enter a time spent, use `/spend 3d 5h 10m`.
-
-Every new time spent entry will be added to the current total time spent for the
-issue or the merge request.
-
-You can remove time by entering a negative amount: `/spend -3d` will remove 3
-days from the total time spent. You can't go below 0 minutes of time spent,
-so GitLab will automatically reset the time spent if you remove a larger amount
-of time compared to the time that was entered already.
-
-To remove all the time spent at once, use `/remove_time_spent`.
-
-## Configuration
-
-The following time units are available:
-
-- Months (mo)
-- Weeks (w)
-- Days (d)
-- Hours (h)
-- Minutes (m)
-
-Default conversion rates are 1mo = 4w, 1w = 5d and 1d = 8h.
-
-### Limit displayed units to hours **(CORE ONLY)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/29469/) in GitLab 12.1.
-
-In GitLab self-managed instances, the display of time units can be limited to
-hours through the option in **Admin Area > Settings > Preferences** under **Localization**.
-
-With this option enabled, `75h` is displayed instead of `1w 4d 3h`.
-
-## Other interesting links
-
-- [Time Tracking landing page in the GitLab handbook](https://about.gitlab.com/solutions/time-tracking/)
+This document was moved to [another location](../user/project/time_tracking.md).
diff --git a/doc/workflow/timezone.md b/doc/workflow/timezone.md
index 3594ba19181..f1a2e1af66a 100644
--- a/doc/workflow/timezone.md
+++ b/doc/workflow/timezone.md
@@ -1,37 +1,5 @@
-# Changing your time zone
+---
+redirect_to: '../administration/timezone.md'
+---
-The global time zone configuration parameter can be changed in `config/gitlab.yml`:
-
-```text
-# time_zone: 'UTC'
-```
-
-Uncomment and customize if you want to change the default time zone of the GitLab application.
-
-## Viewing available timezones
-
-To see all available time zones, run `bundle exec rake time:zones:all`.
-
-For Omnibus installations, run `gitlab-rake time:zones:all`.
-
-NOTE: **Note:**
-Currently, this rake task does not list timezones in TZInfo format required by GitLab Omnibus during a reconfigure: [#58672](https://gitlab.com/gitlab-org/gitlab-foss/issues/58672).
-
-## Changing time zone in Omnibus installations
-
-GitLab defaults its time zone to UTC. It has a global timezone configuration parameter in `/etc/gitlab/gitlab.rb`.
-
-To obtain a list of timezones, log in to your GitLab application server and run a command that generates a list of timezones in TZInfo format for the server. For example, install `timedatectl` and run `timedatectl list-timezones`.
-
-To update, add the timezone that best applies to your location. For example:
-
-```ruby
-gitlab_rails['time_zone'] = 'America/New_York'
-```
-
-After adding the configuration parameter, reconfigure and restart your GitLab instance:
-
-```sh
-gitlab-ctl reconfigure
-gitlab-ctl restart
-```
+This document was moved to [another location](../administration/timezone.md).
diff --git a/doc/workflow/todos.md b/doc/workflow/todos.md
index 5d576d8ff35..48c9a3faf1d 100644
--- a/doc/workflow/todos.md
+++ b/doc/workflow/todos.md
@@ -1,138 +1,5 @@
-# GitLab To-Do List
+---
+redirect_to: '../user/todos.md'
+---
-> [Introduced][ce-2817] in GitLab 8.5.
-
-When you log into GitLab, you normally want to see where you should spend your
-time, take some action, or know what you need to keep an eye on without
-a huge pile of e-mail notifications. GitLab is where you do your work,
-so being able to get started quickly is important.
-
-Your To-Do List offers a chronological list of items that are waiting for your input, all
-in a simple dashboard.
-
-![To Do screenshot showing a list of items to check on](img/todos_index.png)
-
-You can quickly access your To-Do List by clicking the checkmark icon next to the
-search bar in the top navigation. If the count is:
-
-- Less than 100, the number in blue is the number of To-Do items.
-- 100 or more, the number displays as 99+. The exact number displays
- on the To-Do List.
-you still have open. Otherwise, the number displays as 99+. The exact number
-displays on the To-Do List.
-
-![To Do icon](img/todos_icon.png)
-
-## What triggers a To Do
-
-A To Do displays on your To-Do List when:
-
-- An issue or merge request is assigned to you
-- You are `@mentioned` in the description or comment of an:
- - Issue
- - Merge Request
- - Epic **(ULTIMATE)**
-- You are `@mentioned` in a comment on a commit
-- A job in the CI pipeline running for your merge request failed, but this
- job is not allowed to fail
-- An open merge request becomes unmergeable due to conflict, and you are either:
- - The author
- - Have set it to automatically merge once the pipeline succeeds
-
-To-do triggers are not affected by [GitLab Notification Email settings](notifications.md).
-
-NOTE: **Note:**
-When a user no longer has access to a resource related to a To Do (like an issue, merge request, project, or group) the related To-Do items are deleted within the next hour for security reasons. The delete is delayed to prevent data loss, in case the user's access was revoked by mistake.
-
-### Directly addressing a To Do
-
-> [Introduced][ce-7926] in GitLab 9.0.
-
-If you are mentioned at the start of a line, the To Do you receive will be listed
-as 'directly addressed'. For example, in this comment:
-
-```markdown
-@alice What do you think? cc: @bob
-
-- @carol can you please have a look?
-
->>>
-@dan what do you think?
->>>
-
-@erin @frank thank you!
-```
-
-The people receiving directly addressed To-Do items are `@alice`, `@erin`, and
-`@frank`. Directly addressed To-Do items only differ from mentions in their type
-for filtering purposes; otherwise, they appear as normal.
-
-### Manually creating a To Do
-
-You can also add the following to your To-Do List by clicking the **Add a To Do** button on an:
-
-- Issue
-- Merge Request
-- Epic **(ULTIMATE)**
-
-![Adding a To Do from the issuable sidebar](img/todos_add_todo_sidebar.png)
-
-## Marking a To Do as done
-
-Any action to the following will mark the corresponding To Do as done:
-
-- Issue
-- Merge Request
-- Epic **(ULTIMATE)**
-
-Actions that dismiss To-Do items include:
-
-- Changing the assignee
-- Changing the milestone
-- Adding/removing a label
-- Commenting on the issue
-
-Your To-Do List is personal, and items are only marked as done if the action comes from
-you. If you close the issue or merge request, your To Do is automatically
-marked as done.
-
-To prevent other users from closing issues without you being notified, if someone else closes, merges, or takes action on the any of the following, your To Do will remain pending:
-
-- Issue
-- Merge request
-- Epic **(ULTIMATE)**
-
-There is just one To Do for each of these, so mentioning a user a hundred times in an issue will only trigger one To Do.
-
-If no action is needed, you can manually mark the To Do as done by clicking the
-corresponding **Done** button, and it will disappear from your To-Do List.
-
-![A To Do in the To-Do List](img/todo_list_item.png)
-
-You can also mark a To Do as done by clicking the **Mark as done** button in the sidebar of the following:
-
-- Issue
-- Merge Request
-- Epic **(ULTIMATE)**
-
-![Mark as done from the issuable sidebar](img/todos_mark_done_sidebar.png)
-
-You can mark all your To-Do items as done at once by clicking the **Mark all as
-done** button.
-
-## Filtering your To-Do List
-
-There are four kinds of filters you can use on your To-Do List.
-
-| Filter | Description |
-| ------- | ----------- |
-| Project | Filter by project |
-| Group | Filter by group |
-| Author | Filter by the author that triggered the To Do |
-| Type | Filter by issue, merge request, or epic **(ULTIMATE)** |
-| Action | Filter by the action that triggered the To Do |
-
-You can also filter by more than one of these at the same time. The possible Actions are `Any Action`, `Assigned`, `Mentioned`, `Added`, `Pipelines`, and `Directly Addressed`, [as described above](#what-triggers-a-to-do).
-
-[ce-2817]: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/2817
-[ce-7926]: https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/7926
+This document was moved to [another location](../user/todos.md).
diff --git a/doc/workflow/workflow.md b/doc/workflow/workflow.md
index 7fac41c3b6f..c77d95cd326 100644
--- a/doc/workflow/workflow.md
+++ b/doc/workflow/workflow.md
@@ -1,31 +1,5 @@
-# Feature branch workflow
+---
+redirect_to: '../gitlab-basics/feature_branch_workflow.md'
+---
-1. Clone project:
-
- ```bash
- git clone git@example.com:project-name.git
- ```
-
-1. Create branch with your feature:
-
- ```bash
- git checkout -b $feature_name
- ```
-
-1. Write code. Commit changes:
-
- ```bash
- git commit -am "My feature is ready"
- ```
-
-1. Push your branch to GitLab:
-
- ```bash
- git push origin $feature_name
- ```
-
-1. Review your code on commits page.
-
-1. Create a merge request.
-
-1. Your team lead will review the code &amp; merge it to the main branch.
+This document was moved to [another location](../gitlab-basics/feature_branch_workflow.md).
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index de12695af37..444031fd68d 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -777,6 +777,10 @@ module API
expose :squash
expose :task_completion_status
+
+ expose :cannot_be_merged?, as: :has_conflicts
+
+ expose :mergeable_discussions_state?, as: :blocking_discussions_resolved
end
class MergeRequest < MergeRequestBasic
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 2ccc8a367aa..948f720b01b 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -38,7 +38,8 @@ module Gitlab
cookies.permanent.signed[:experimentation_subject_id] = {
value: SecureRandom.uuid,
domain: :all,
- secure: ::Gitlab.config.gitlab.https
+ secure: ::Gitlab.config.gitlab.https,
+ httponly: true
}
end
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index b0f29d22ad4..9e3af00e00d 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -142,18 +142,39 @@ module Gitlab
# kwargs.merge(deadline: Time.now + 10)
# end
#
- def self.call(storage, service, rpc, request, remote_storage: nil, timeout: default_timeout)
- start = Gitlab::Metrics::System.monotonic_time
- request_hash = request.is_a?(Google::Protobuf::MessageExts) ? request.to_h : {}
+ def self.call(storage, service, rpc, request, remote_storage: nil, timeout: default_timeout, &block)
+ self.measure_timings(service, rpc, request) do
+ self.execute(storage, service, rpc, request, remote_storage: remote_storage, timeout: timeout, &block)
+ end
+ end
+ # This method is like GitalyClient.call but should be used with
+ # Gitaly streaming RPCs. It measures how long the the RPC took to
+ # produce the full response, not just the initial response.
+ def self.streaming_call(storage, service, rpc, request, remote_storage: nil, timeout: default_timeout)
+ self.measure_timings(service, rpc, request) do
+ response = self.execute(storage, service, rpc, request, remote_storage: remote_storage, timeout: timeout)
+
+ yield(response)
+ end
+ end
+
+ def self.execute(storage, service, rpc, request, remote_storage:, timeout:)
enforce_gitaly_request_limits(:call)
kwargs = request_kwargs(storage, timeout: timeout.to_f, remote_storage: remote_storage)
kwargs = yield(kwargs) if block_given?
stub(service, storage).__send__(rpc, request, kwargs) # rubocop:disable GitlabSecurity/PublicSend
+ end
+
+ def self.measure_timings(service, rpc, request)
+ start = Gitlab::Metrics::System.monotonic_time
+
+ yield
ensure
duration = Gitlab::Metrics::System.monotonic_time - start
+ request_hash = request.is_a?(Google::Protobuf::MessageExts) ? request.to_h : {}
# Keep track, separately, for the performance bar
self.query_time += duration
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index dca55091be6..15318bc817a 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -200,8 +200,9 @@ module Gitlab
to: to
)
- response = GitalyClient.call(@repository.storage, :commit_service, :commits_between, request, timeout: GitalyClient.medium_timeout)
- consume_commits_response(response)
+ GitalyClient.streaming_call(@repository.storage, :commit_service, :commits_between, request, timeout: GitalyClient.medium_timeout) do |response|
+ consume_commits_response(response)
+ end
end
def diff_stats(left_commit_sha, right_commit_sha)
@@ -224,8 +225,9 @@ module Gitlab
)
request.order = opts[:order].upcase if opts[:order].present?
- response = GitalyClient.call(@repository.storage, :commit_service, :find_all_commits, request, timeout: GitalyClient.medium_timeout)
- consume_commits_response(response)
+ GitalyClient.streaming_call(@repository.storage, :commit_service, :find_all_commits, request, timeout: GitalyClient.medium_timeout) do |response|
+ consume_commits_response(response)
+ end
end
def list_commits_by_oid(oids)
@@ -233,8 +235,9 @@ module Gitlab
request = Gitaly::ListCommitsByOidRequest.new(repository: @gitaly_repo, oid: oids)
- response = GitalyClient.call(@repository.storage, :commit_service, :list_commits_by_oid, request, timeout: GitalyClient.medium_timeout)
- consume_commits_response(response)
+ GitalyClient.streaming_call(@repository.storage, :commit_service, :list_commits_by_oid, request, timeout: GitalyClient.medium_timeout) do |response|
+ consume_commits_response(response)
+ end
rescue GRPC::NotFound # If no repository is found, happens mainly during testing
[]
end
@@ -249,8 +252,9 @@ module Gitlab
offset: offset.to_i
)
- response = GitalyClient.call(@repository.storage, :commit_service, :commits_by_message, request, timeout: GitalyClient.medium_timeout)
- consume_commits_response(response)
+ GitalyClient.streaming_call(@repository.storage, :commit_service, :commits_by_message, request, timeout: GitalyClient.medium_timeout) do |response|
+ consume_commits_response(response)
+ end
end
def languages(ref = nil)
@@ -323,9 +327,9 @@ module Gitlab
request.paths = encode_repeated(Array(options[:path])) if options[:path].present?
- response = GitalyClient.call(@repository.storage, :commit_service, :find_commits, request, timeout: GitalyClient.medium_timeout)
-
- consume_commits_response(response)
+ GitalyClient.streaming_call(@repository.storage, :commit_service, :find_commits, request, timeout: GitalyClient.medium_timeout) do |response|
+ consume_commits_response(response)
+ end
end
def filter_shas_with_signatures(shas)
diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
index 3fa5765fd4a..9433a231b4a 100644
--- a/lib/gitlab/import_export/project_tree_restorer.rb
+++ b/lib/gitlab/import_export/project_tree_restorer.rb
@@ -120,10 +120,6 @@ module Gitlab
end
end
- def remove_feature_dependent_sub_relations!(_relation_item)
- # no-op
- end
-
def project_relations
@project_relations ||= reader.attributes_finder.find_relations_tree(:project)
end
@@ -175,8 +171,6 @@ module Gitlab
# Avoid keeping a possible heavy object in memory once we are done with it
while relation_item = tree_array.shift
- remove_feature_dependent_sub_relations!(relation_item)
-
# The transaction at this level is less speedy than one single transaction
# But we can't have it in the upper level or GC won't get rid of the AR objects
# after we save the batch.
@@ -241,5 +235,3 @@ module Gitlab
end
end
end
-
-Gitlab::ImportExport::ProjectTreeRestorer.prepend_if_ee('::EE::Gitlab::ImportExport::ProjectTreeRestorer')
diff --git a/lib/gitlab/instrumentation_helper.rb b/lib/gitlab/instrumentation_helper.rb
index e6a5facb2a5..edaa9c645b4 100644
--- a/lib/gitlab/instrumentation_helper.rb
+++ b/lib/gitlab/instrumentation_helper.rb
@@ -21,5 +21,49 @@ module Gitlab
payload[:rugged_duration_ms] = Gitlab::RuggedInstrumentation.query_time_ms
end
end
+
+ # Returns the queuing duration for a Sidekiq job in seconds, as a float, if the
+ # `enqueued_at` field or `created_at` field is available.
+ #
+ # * If the job doesn't contain sufficient information, returns nil
+ # * If the job has a start time in the future, returns 0
+ # * If the job contains an invalid start time value, returns nil
+ # @param [Hash] job a Sidekiq job, represented as a hash
+ def self.queue_duration_for_job(job)
+ # Old gitlab-shell messages don't provide enqueued_at/created_at attributes
+ enqueued_at = job['enqueued_at'] || job['created_at']
+ return unless enqueued_at
+
+ enqueued_at_time = convert_to_time(enqueued_at)
+ return unless enqueued_at_time
+
+ # Its possible that if theres clock-skew between two nodes
+ # this value may be less than zero. In that event, we record the value
+ # as zero.
+ [elapsed_by_absolute_time(enqueued_at_time), 0].max
+ end
+
+ # Calculates the time in seconds, as a float, from
+ # the provided start time until now
+ #
+ # @param [Time] start
+ def self.elapsed_by_absolute_time(start)
+ (Time.now - start).to_f.round(6)
+ end
+ private_class_method :elapsed_by_absolute_time
+
+ # Convert a representation of a time into a `Time` value
+ #
+ # @param time_value String, Float time representation, or nil
+ def self.convert_to_time(time_value)
+ return time_value if time_value.is_a?(Time)
+ return Time.iso8601(time_value) if time_value.is_a?(String)
+ return Time.at(time_value) if time_value.is_a?(Numeric) && time_value > 0
+ rescue ArgumentError
+ # Swallow invalid dates. Better to loose some observability
+ # than bring all background processing down because of a date
+ # formatting bug in a client
+ end
+ private_class_method :convert_to_time
end
end
diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb
index 853fb2777c3..ca9e3b8428c 100644
--- a/lib/gitlab/sidekiq_logging/structured_logger.rb
+++ b/lib/gitlab/sidekiq_logging/structured_logger.rb
@@ -36,11 +36,8 @@ module Gitlab
payload['message'] = "#{base_message(payload)}: start"
payload['job_status'] = 'start'
- # Old gitlab-shell messages don't provide enqueued_at/created_at attributes
- enqueued_at = payload['enqueued_at'] || payload['created_at']
- if enqueued_at
- payload['scheduling_latency_s'] = elapsed_by_absolute_time(Time.iso8601(enqueued_at))
- end
+ scheduling_latency_s = ::Gitlab::InstrumentationHelper.queue_duration_for_job(payload)
+ payload['scheduling_latency_s'] = scheduling_latency_s if scheduling_latency_s
payload
end
@@ -98,10 +95,6 @@ module Gitlab
end
end
- def elapsed_by_absolute_time(start)
- (Time.now.utc - start).to_f.round(6)
- end
-
def elapsed(t0)
t1 = get_time
{
diff --git a/lib/gitlab/sidekiq_middleware/metrics.rb b/lib/gitlab/sidekiq_middleware/metrics.rb
index d45045ca414..bd819843bd4 100644
--- a/lib/gitlab/sidekiq_middleware/metrics.rb
+++ b/lib/gitlab/sidekiq_middleware/metrics.rb
@@ -15,6 +15,9 @@ module Gitlab
def call(_worker, job, queue)
labels = create_labels(queue)
+ queue_duration = ::Gitlab::InstrumentationHelper.queue_duration_for_job(job)
+
+ @metrics[:sidekiq_jobs_queue_duration_seconds].observe(labels, queue_duration) if queue_duration
@metrics[:sidekiq_running_jobs].increment(labels, 1)
if job['retry_count'].present?
@@ -49,12 +52,13 @@ module Gitlab
def init_metrics
{
- sidekiq_jobs_cpu_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_cpu_seconds, 'Seconds of cpu time to run sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_completion_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_completion_seconds, 'Seconds to complete sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
- sidekiq_jobs_failed_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_failed_total, 'Sidekiq jobs failed'),
- sidekiq_jobs_retried_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_retried_total, 'Sidekiq jobs retried'),
- sidekiq_running_jobs: ::Gitlab::Metrics.gauge(:sidekiq_running_jobs, 'Number of Sidekiq jobs running', {}, :all),
- sidekiq_concurrency: ::Gitlab::Metrics.gauge(:sidekiq_concurrency, 'Maximum number of Sidekiq jobs', {}, :all)
+ sidekiq_jobs_cpu_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_cpu_seconds, 'Seconds of cpu time to run Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_completion_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_completion_seconds, 'Seconds to complete Sidekiq job', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_queue_duration_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_queue_duration_seconds, 'Duration in seconds that a Sidekiq job was queued before being executed', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_failed_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_failed_total, 'Sidekiq jobs failed'),
+ sidekiq_jobs_retried_total: ::Gitlab::Metrics.counter(:sidekiq_jobs_retried_total, 'Sidekiq jobs retried'),
+ sidekiq_running_jobs: ::Gitlab::Metrics.gauge(:sidekiq_running_jobs, 'Number of Sidekiq jobs running', {}, :all),
+ sidekiq_concurrency: ::Gitlab::Metrics.gauge(:sidekiq_concurrency, 'Maximum number of Sidekiq jobs', {}, :all)
}
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 07d54a9a696..1e47dd679ac 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4391,6 +4391,9 @@ msgstr ""
msgid "Container registry images"
msgstr ""
+msgid "Container registry is not enabled on this GitLab instance. Ask an administrator to enable it in order for AutoDevOps to work."
+msgstr ""
+
msgid "ContainerRegistry|Container Registry"
msgstr ""
@@ -8653,6 +8656,9 @@ msgstr[1] ""
msgid "Hide values"
msgstr ""
+msgid "Hiding all labels"
+msgstr ""
+
msgid "Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0."
msgstr ""
@@ -14810,6 +14816,9 @@ msgstr ""
msgid "Select user"
msgstr ""
+msgid "Select your role"
+msgstr ""
+
msgid "Selected levels cannot be used by non-admin users for groups, projects or snippets. If the public level is restricted, user profiles are only visible to logged in users."
msgstr ""
@@ -15175,6 +15184,9 @@ msgstr ""
msgid "Showing all issues"
msgstr ""
+msgid "Showing all labels"
+msgstr ""
+
msgid "Showing last %{size} of log -"
msgstr ""
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
index e45ce438fc2..9dc4bcc8a03 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
@@ -6,6 +6,10 @@ module QA
context 'Release', :docker do
describe 'Git clone using a deploy key' do
before do
+ # Handle WIP Job Logs flag - https://gitlab.com/gitlab-org/gitlab/issues/31162
+ @job_log_json_flag_enabled = Runtime::Feature.enabled?('job_log_json')
+ Runtime::Feature.disable('job_log_json') if @job_log_json_flag_enabled
+
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
@@ -26,6 +30,7 @@ module QA
end
after do
+ Runtime::Feature.enable('job_log_json') if @job_log_json_flag_enabled
Service::DockerRun::GitlabRunner.new(@runner_name).remove!
end
diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb
index e0a3605d50a..4f4f9e5143b 100644
--- a/spec/controllers/groups/milestones_controller_spec.rb
+++ b/spec/controllers/groups/milestones_controller_spec.rb
@@ -314,6 +314,24 @@ describe Groups::MilestonesController do
expect(controller).to set_flash[:notice].to(group_moved_message(redirect_route, group))
end
+ context 'with an AJAX request' do
+ it 'redirects to the canonical path but does not set flash message' do
+ get :merge_requests, params: { group_id: redirect_route.path, id: title }, xhr: true
+
+ expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title))
+ expect(controller).not_to set_flash[:notice]
+ end
+ end
+
+ context 'with JSON format' do
+ it 'redirects to the canonical path but does not set flash message' do
+ get :merge_requests, params: { group_id: redirect_route.path, id: title }, format: :json
+
+ expect(response).to redirect_to(merge_requests_group_milestone_path(group.to_param, title, format: :json))
+ expect(controller).not_to set_flash[:notice]
+ end
+ end
+
context 'when the old group path is a substring of the scheme or host' do
let(:redirect_route) { group.redirect_routes.create(path: 'http') }
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index ff089df37f7..aee017b211a 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -204,6 +204,24 @@ describe Projects::LabelsController do
expect(response).to redirect_to(project_labels_path(project))
expect(controller).to set_flash[:notice].to(project_moved_message(redirect_route, project))
end
+
+ context 'with an AJAX request' do
+ it 'redirects to the canonical path but does not set flash message' do
+ get :index, params: { namespace_id: project.namespace, project_id: project.to_param + 'old' }, xhr: true
+
+ expect(response).to redirect_to(project_labels_path(project))
+ expect(controller).not_to set_flash[:notice]
+ end
+ end
+
+ context 'with JSON format' do
+ it 'redirects to the canonical path but does not set flash message' do
+ get :index, params: { namespace_id: project.namespace, project_id: project.to_param + 'old' }, format: :json
+
+ expect(response).to redirect_to(project_labels_path(project, format: :json))
+ expect(controller).not_to set_flash[:notice]
+ end
+ end
end
end
end
diff --git a/spec/features/populate_new_pipeline_vars_with_params_spec.rb b/spec/features/populate_new_pipeline_vars_with_params_spec.rb
new file mode 100644
index 00000000000..5fe80e73e38
--- /dev/null
+++ b/spec/features/populate_new_pipeline_vars_with_params_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe "Populate new pipeline CI variables with url params", :js do
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:page_path) { new_project_pipeline_path(project) }
+
+ before do
+ sign_in(user)
+ project.add_maintainer(user)
+
+ visit "#{page_path}?var[key1]=value1&file_var[key2]=value2"
+ end
+
+ it "var[key1]=value1 populates env_var variable correctly" do
+ page.within('.ci-variable-list .js-row:nth-child(1)') do
+ expect(find('.js-ci-variable-input-variable-type').value).to eq('env_var')
+ expect(find('.js-ci-variable-input-key').value).to eq('key1')
+ expect(find('.js-ci-variable-input-value').text).to eq('value1')
+ end
+ end
+
+ it "file_var[key2]=value2 populates file variable correctly" do
+ page.within('.ci-variable-list .js-row:nth-child(2)') do
+ expect(find('.js-ci-variable-input-variable-type').value).to eq('file')
+ expect(find('.js-ci-variable-input-key').value).to eq('key2')
+ expect(find('.js-ci-variable-input-value').text).to eq('value2')
+ end
+ end
+end
diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb
index 0905ab0aef8..23f660d111a 100644
--- a/spec/features/profiles/user_edit_profile_spec.rb
+++ b/spec/features/profiles/user_edit_profile_spec.rb
@@ -66,6 +66,34 @@ describe 'User edit profile' do
end
end
+ describe 'when I change my role' do
+ context 'experiment enabled' do
+ before do
+ stub_experiment_for_user(signup_flow: true)
+ visit(profile_path)
+ end
+
+ it 'changes my role' do
+ expect(page).to have_content 'Role'
+ select 'Data Analyst', from: 'user_role'
+ submit_settings
+ user.reload
+ expect(user.role).to eq 'data_analyst'
+ end
+ end
+
+ context 'experiment disabled' do
+ before do
+ stub_experiment_for_user(signup_flow: false)
+ visit(profile_path)
+ end
+
+ it 'does not show the role picker' do
+ expect(page).not_to have_content 'Role'
+ end
+ end
+ end
+
context 'user avatar' do
before do
attach_file(:user_avatar, Rails.root.join('spec', 'fixtures', 'banana_sample.gif'))
diff --git a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
index baf715000a3..df63856492e 100644
--- a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
@@ -57,5 +57,18 @@ describe 'Project > Show > User interacts with auto devops implicitly enabled ba
expect(page).not_to have_css('.auto-devops-implicitly-enabled-banner')
end
end
+
+ context 'when AutoDevOps enabled but container registry is disabled' do
+ before do
+ stub_application_setting(auto_devops_enabled: true)
+ stub_container_registry_config(enabled: false)
+
+ visit project_path(project)
+ end
+
+ it 'shows message that container registry is disabled' do
+ expect(page).to have_content('Container registry is not enabled on this GitLab instance')
+ end
+ end
end
end
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index a4b076bc367..6234d596745 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -140,6 +140,29 @@ describe TodosFinder do
end
end
end
+
+ context 'by state' do
+ let!(:todo1) { create(:todo, user: user, group: group, target: issue, state: :done) }
+ let!(:todo2) { create(:todo, user: user, group: group, target: issue, state: :pending) }
+
+ it 'returns the expected items when no state is provided' do
+ todos = finder.new(user, {}).execute
+
+ expect(todos).to match_array([todo2])
+ end
+
+ it 'returns the expected items when a state is provided' do
+ todos = finder.new(user, { state: :done }).execute
+
+ expect(todos).to match_array([todo1])
+ end
+
+ it 'returns the expected items when multiple states are provided' do
+ todos = finder.new(user, { state: [:pending, :done] }).execute
+
+ expect(todos).to match_array([todo1, todo2])
+ end
+ end
end
context 'external authorization' do
diff --git a/spec/frontend/boards/stores/getters_spec.js b/spec/frontend/boards/stores/getters_spec.js
new file mode 100644
index 00000000000..38b2333e679
--- /dev/null
+++ b/spec/frontend/boards/stores/getters_spec.js
@@ -0,0 +1,21 @@
+import getters from '~/boards/stores/getters';
+
+describe('Boards - Getters', () => {
+ describe('getLabelToggleState', () => {
+ it('should return "on" when isShowingLabels is true', () => {
+ const state = {
+ isShowingLabels: true,
+ };
+
+ expect(getters.getLabelToggleState(state)).toBe('on');
+ });
+
+ it('should return "off" when isShowingLabels is false', () => {
+ const state = {
+ isShowingLabels: false,
+ };
+
+ expect(getters.getLabelToggleState(state)).toBe('off');
+ });
+ });
+});
diff --git a/spec/frontend/error_tracking/store/getters_spec.js b/spec/frontend/error_tracking/store/getters_spec.js
new file mode 100644
index 00000000000..371dfae373b
--- /dev/null
+++ b/spec/frontend/error_tracking/store/getters_spec.js
@@ -0,0 +1,33 @@
+import * as getters from '~/error_tracking/store/getters';
+
+describe('Error Tracking getters', () => {
+ let state;
+
+ const mockErrors = [
+ { title: 'ActiveModel::MissingAttributeError: missing attribute: encrypted_password' },
+ { title: 'Grape::Exceptions::MethodNotAllowed: Grape::Exceptions::MethodNotAllowed' },
+ { title: 'NoMethodError: undefined method `sanitize_http_headers=' },
+ { title: 'NoMethodError: undefined method `pry' },
+ ];
+
+ beforeEach(() => {
+ state = {
+ errors: mockErrors,
+ };
+ });
+
+ describe('search results', () => {
+ it('should return errors filtered by words in title matching the query', () => {
+ const filteredErrors = getters.filterErrorsByTitle(state)('NoMethod');
+
+ expect(filteredErrors).not.toContainEqual(mockErrors[0]);
+ expect(filteredErrors.length).toBe(2);
+ });
+
+ it('should not return results if there is no matching query', () => {
+ const filteredErrors = getters.filterErrorsByTitle(state)('GitLab');
+
+ expect(filteredErrors.length).toBe(0);
+ });
+ });
+});
diff --git a/spec/frontend/releases/list/components/release_block_spec.js b/spec/frontend/releases/list/components/release_block_spec.js
index 0b908d7d6bc..ac51c3af11a 100644
--- a/spec/frontend/releases/list/components/release_block_spec.js
+++ b/spec/frontend/releases/list/components/release_block_spec.js
@@ -39,13 +39,25 @@ describe('Release block', () => {
const milestoneListLabel = () => wrapper.find('.js-milestone-list-label');
const editButton = () => wrapper.find('.js-edit-button');
+ const RealDate = Date;
beforeEach(() => {
+ // timeago.js calls Date(), so let's mock that case to avoid time-dependent test failures.
+ const constantDate = new Date('2019-10-25T00:12:00');
+
+ /* eslint no-global-assign:off */
+ global.Date = jest.fn((...props) =>
+ props.length ? new RealDate(...props) : new RealDate(constantDate),
+ );
+
+ Object.assign(Date, RealDate);
+
releaseClone = JSON.parse(JSON.stringify(release));
});
afterEach(() => {
wrapper.destroy();
+ global.Date = RealDate;
});
describe('with default props', () => {
diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js
index 9f441ca319e..51433a58212 100644
--- a/spec/javascripts/boards/board_card_spec.js
+++ b/spec/javascripts/boards/board_card_spec.js
@@ -10,6 +10,7 @@ import eventHub from '~/boards/eventhub';
import '~/boards/models/label';
import '~/boards/models/assignee';
import '~/boards/models/list';
+import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
import boardCard from '~/boards/components/board_card.vue';
import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
@@ -40,6 +41,7 @@ describe('Board card', () => {
list.issues[0].labels.push(label1);
vm = new BoardCardComp({
+ store,
propsData: {
list,
issue: list.issues[0],
diff --git a/spec/javascripts/boards/board_list_common_spec.js b/spec/javascripts/boards/board_list_common_spec.js
index cb337e4cc83..5cd17323d0d 100644
--- a/spec/javascripts/boards/board_list_common_spec.js
+++ b/spec/javascripts/boards/board_list_common_spec.js
@@ -10,6 +10,7 @@ import BoardList from '~/boards/components/board_list.vue';
import '~/boards/models/issue';
import '~/boards/models/list';
import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
+import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
window.Sortable = Sortable;
@@ -39,6 +40,7 @@ export default function createComponent({ done, listIssueProps = {}, componentPr
const component = new BoardListComp({
el,
+ store,
propsData: {
disabled: false,
list,
diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js
index 314e051665e..df2b04cd6df 100644
--- a/spec/javascripts/boards/issue_card_spec.js
+++ b/spec/javascripts/boards/issue_card_spec.js
@@ -10,6 +10,7 @@ import '~/boards/models/issue';
import '~/boards/models/list';
import IssueCardInner from '~/boards/components/issue_card_inner.vue';
import { listObj } from './mock_data';
+import store from '~/boards/stores';
describe('Issue card component', () => {
const user = new ListAssignee({
@@ -50,6 +51,7 @@ describe('Issue card component', () => {
component = new Vue({
el: document.querySelector('.test-container'),
+ store,
components: {
'issue-card': IssueCardInner,
},
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index ea3bb12d049..67fe89f3fbe 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -377,6 +377,8 @@ describe Gitlab::GitalyClient do
context 'when the request store is active', :request_store do
it 'records call details if a RPC is called' do
+ expect(described_class).to receive(:measure_timings).and_call_original
+
gitaly_server.server_version
expect(described_class.list_call_details).not_to be_empty
diff --git a/spec/lib/gitlab/instrumentation_helper_spec.rb b/spec/lib/gitlab/instrumentation_helper_spec.rb
new file mode 100644
index 00000000000..c2674638743
--- /dev/null
+++ b/spec/lib/gitlab/instrumentation_helper_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'rspec-parameterized'
+
+describe Gitlab::InstrumentationHelper do
+ using RSpec::Parameterized::TableSyntax
+
+ describe '.queue_duration_for_job' do
+ where(:enqueued_at, :created_at, :time_now, :expected_duration) do
+ "2019-06-01T00:00:00.000+0000" | nil | "2019-06-01T02:00:00.000+0000" | 2.hours.to_f
+ "2019-06-01T02:00:00.000+0000" | nil | "2019-06-01T02:00:00.001+0000" | 0.001
+ "2019-06-01T02:00:00.000+0000" | "2019-05-01T02:00:00.000+0000" | "2019-06-01T02:00:01.000+0000" | 1
+ nil | "2019-06-01T02:00:00.000+0000" | "2019-06-01T02:00:00.001+0000" | 0.001
+ nil | nil | "2019-06-01T02:00:00.001+0000" | nil
+ "2019-06-01T02:00:00.000+0200" | nil | "2019-06-01T02:00:00.000-0200" | 4.hours.to_f
+ 1571825569.998168 | nil | "2019-10-23T12:13:16.000+0200" | 26.001832
+ 1571825569 | nil | "2019-10-23T12:13:16.000+0200" | 27
+ "invalid_date" | nil | "2019-10-23T12:13:16.000+0200" | nil
+ "" | nil | "2019-10-23T12:13:16.000+0200" | nil
+ 0 | nil | "2019-10-23T12:13:16.000+0200" | nil
+ -1 | nil | "2019-10-23T12:13:16.000+0200" | nil
+ "2019-06-01T02:00:00.000+0000" | nil | "2019-06-01T00:00:00.000+0000" | 0
+ Time.at(1571999233) | nil | "2019-10-25T12:29:16.000+0200" | 123
+ end
+
+ with_them do
+ let(:job) { { 'enqueued_at' => enqueued_at, 'created_at' => created_at } }
+
+ it "returns the correct duration" do
+ Timecop.freeze(Time.iso8601(time_now)) do
+ expect(described_class.queue_duration_for_job(job)).to eq(expected_duration)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
index 46fbc069efb..cb870cc996b 100644
--- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
+++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
describe Gitlab::SidekiqLogging::StructuredLogger do
describe '#call' do
diff --git a/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb
index df16b9d073c..0d8cff3a295 100644
--- a/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/metrics_spec.rb
@@ -1,11 +1,12 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
describe Gitlab::SidekiqMiddleware::Metrics do
let(:middleware) { described_class.new }
-
let(:concurrency_metric) { double('concurrency metric') }
+
+ let(:queue_duration_seconds) { double('queue duration seconds metric') }
let(:completion_seconds_metric) { double('completion seconds metric') }
let(:user_execution_seconds_metric) { double('user execution seconds metric') }
let(:failed_total_metric) { double('failed total metric') }
@@ -13,6 +14,7 @@ describe Gitlab::SidekiqMiddleware::Metrics do
let(:running_jobs_metric) { double('running jobs metric') }
before do
+ allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_queue_duration_seconds, anything, anything, anything).and_return(queue_duration_seconds)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_completion_seconds, anything, anything, anything).and_return(completion_seconds_metric)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_cpu_seconds, anything, anything, anything).and_return(user_execution_seconds_metric)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_failed_total, anything).and_return(failed_total_metric)
@@ -20,7 +22,6 @@ describe Gitlab::SidekiqMiddleware::Metrics do
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_running_jobs, anything, {}, :all).and_return(running_jobs_metric)
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_concurrency, anything, {}, :all).and_return(concurrency_metric)
- allow(running_jobs_metric).to receive(:increment)
allow(concurrency_metric).to receive(:set)
end
@@ -32,62 +33,76 @@ describe Gitlab::SidekiqMiddleware::Metrics do
end
end
+ it 'ignore user execution when measured 0' do
+ allow(completion_seconds_metric).to receive(:observe)
+
+ expect(user_execution_seconds_metric).not_to receive(:observe)
+ end
+
describe '#call' do
let(:worker) { double(:worker) }
- it 'yields block' do
- allow(completion_seconds_metric).to receive(:observe)
- allow(user_execution_seconds_metric).to receive(:observe)
+ let(:job) { {} }
+ let(:job_status) { :done }
+ let(:labels) { { queue: :test } }
+ let(:labels_with_job_status) { { queue: :test, job_status: job_status } }
- expect { |b| middleware.call(worker, {}, :test, &b) }.to yield_control.once
- end
+ let(:thread_cputime_before) { 1 }
+ let(:thread_cputime_after) { 2 }
+ let(:thread_cputime_duration) { thread_cputime_after - thread_cputime_before }
- it 'sets queue specific metrics' do
- labels = { queue: :test }
- labels_with_job_status = { queue: :test, job_status: :done }
- allow(middleware).to receive(:get_thread_cputime).and_return(1, 3)
- allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(2, 3)
+ let(:monotonic_time_before) { 11 }
+ let(:monotonic_time_after) { 20 }
+ let(:monotonic_time_duration) { monotonic_time_after - monotonic_time_before }
+
+ let(:queue_duration_for_job) { 0.01 }
+
+ before do
+ allow(middleware).to receive(:get_thread_cputime).and_return(thread_cputime_before, thread_cputime_after)
+ allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(monotonic_time_before, monotonic_time_after)
+ allow(Gitlab::InstrumentationHelper).to receive(:queue_duration_for_job).with(job).and_return(queue_duration_for_job)
expect(running_jobs_metric).to receive(:increment).with(labels, 1)
expect(running_jobs_metric).to receive(:increment).with(labels, -1)
- expect(user_execution_seconds_metric).to receive(:observe).with(labels_with_job_status, 2)
- expect(completion_seconds_metric).to receive(:observe).with(labels_with_job_status, 1)
- middleware.call(worker, {}, :test) { nil }
+ expect(queue_duration_seconds).to receive(:observe).with(labels, queue_duration_for_job) if queue_duration_for_job
+ expect(user_execution_seconds_metric).to receive(:observe).with(labels_with_job_status, thread_cputime_duration)
+ expect(completion_seconds_metric).to receive(:observe).with(labels_with_job_status, monotonic_time_duration)
end
- it 'ignore user execution when measured 0' do
- allow(completion_seconds_metric).to receive(:observe)
- allow(middleware).to receive(:get_thread_cputime).and_return(0, 0)
+ it 'yields block' do
+ expect { |b| middleware.call(worker, job, :test, &b) }.to yield_control.once
+ end
+
+ it 'sets queue specific metrics' do
+ middleware.call(worker, job, :test) { nil }
+ end
+
+ context 'when job_duration is not available' do
+ let(:queue_duration_for_job) { nil }
- expect(user_execution_seconds_metric).not_to receive(:observe)
+ it 'does not set the queue_duration_seconds histogram' do
+ middleware.call(worker, job, :test) { nil }
+ end
end
context 'when job is retried' do
- it 'sets sidekiq_jobs_retried_total metric' do
- allow(completion_seconds_metric).to receive(:observe)
- expect(user_execution_seconds_metric).to receive(:observe)
+ let(:job) { { 'retry_count' => 1 } }
+ it 'sets sidekiq_jobs_retried_total metric' do
expect(retried_total_metric).to receive(:increment)
- middleware.call(worker, { 'retry_count' => 1 }, :test) { nil }
+ middleware.call(worker, job, :test) { nil }
end
end
context 'when error is raised' do
- it 'sets sidekiq_jobs_failed_total and reraises' do
- labels = { queue: :test }
- labels_with_job_status = { queue: :test, job_status: :fail }
- allow(middleware).to receive(:get_thread_cputime).and_return(1, 4)
- allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(2, 6)
+ let(:job_status) { :fail }
- expect(running_jobs_metric).to receive(:increment).with(labels, 1)
- expect(running_jobs_metric).to receive(:increment).with(labels, -1)
+ it 'sets sidekiq_jobs_failed_total and reraises' do
expect(failed_total_metric).to receive(:increment).with(labels, 1)
- expect(user_execution_seconds_metric).to receive(:observe).with(labels_with_job_status, 3)
- expect(completion_seconds_metric).to receive(:observe).with(labels_with_job_status, 4)
- expect { middleware.call(worker, {}, :test) { raise StandardError, "Failed" } }.to raise_error(StandardError, "Failed")
+ expect { middleware.call(worker, job, :test) { raise StandardError, "Failed" } }.to raise_error(StandardError, "Failed")
end
end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 721998ede6a..443682cd34c 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -775,6 +775,8 @@ describe API::MergeRequests do
expect(json_response['merge_error']).to eq(merge_request.merge_error)
expect(json_response['user']['can_merge']).to be_truthy
expect(json_response).not_to include('rebase_in_progress')
+ expect(json_response['has_conflicts']).to be_falsy
+ expect(json_response['blocking_discussions_resolved']).to be_truthy
end
it 'exposes description and title html when render_html is true' do
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 1cabfb55803..67c8056becb 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -450,16 +450,22 @@ describe 'Git HTTP requests' do
context "when authentication fails" do
context "when the user is IP banned" do
before do
- Gitlab.config.rack_attack.git_basic_auth['enabled'] = true
+ stub_rack_attack_setting(enabled: true)
end
- it "responds with status 401" do
+ it "responds with status 403" do
expect(Rack::Attack::Allow2Ban).to receive(:filter).and_return(true)
- allow_any_instance_of(ActionDispatch::Request).to receive(:ip).and_return('1.2.3.4')
+ expect(Gitlab::AuthLogger).to receive(:error).with({
+ message: 'Rack_Attack',
+ env: :blocklist,
+ remote_ip: '127.0.0.1',
+ request_method: 'GET',
+ path: "/#{path}/info/refs?service=git-upload-pack"
+ })
clone_get(path, env)
- expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
@@ -493,7 +499,7 @@ describe 'Git HTTP requests' do
context "when the user isn't blocked" do
before do
- Gitlab.config.rack_attack.git_basic_auth['enabled'] = true
+ stub_rack_attack_setting(enabled: true, bantime: 1.minute, findtime: 5.minutes, maxretry: 2, ip_whitelist: [])
end
it "resets the IP in Rack Attack on download" do
@@ -652,9 +658,11 @@ describe 'Git HTTP requests' do
response.status
end
+ include_context 'rack attack cache store'
+
it "repeated attempts followed by successful attempt" do
options = Gitlab.config.rack_attack.git_basic_auth
- maxretry = options[:maxretry] - 1
+ maxretry = options[:maxretry]
ip = '1.2.3.4'
allow_any_instance_of(ActionDispatch::Request).to receive(:ip).and_return(ip)
@@ -666,12 +674,6 @@ describe 'Git HTTP requests' do
expect(attempt_login(true)).to eq(200)
expect(Rack::Attack::Allow2Ban.banned?(ip)).to be_falsey
-
- maxretry.times.each do
- expect(attempt_login(false)).to eq(401)
- end
-
- Rack::Attack::Allow2Ban.reset(ip, options)
end
end
diff --git a/spec/services/projects/container_repository/delete_tags_service_spec.rb b/spec/services/projects/container_repository/delete_tags_service_spec.rb
index f296ef3a776..91b668495d8 100644
--- a/spec/services/projects/container_repository/delete_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/delete_tags_service_spec.rb
@@ -57,21 +57,7 @@ describe Projects::ContainerRepository::DeleteTagsService do
end
end
- context 'with dummy tags disabled' do
- let(:tags) { %w[A Ba] }
-
- before do
- stub_feature_flags(container_registry_smart_delete: false)
- end
-
- it 'deletes tags one by one' do
- expect_delete_tag('sha256:configA')
- expect_delete_tag('sha256:configB')
- is_expected.to include(status: :success)
- end
- end
-
- context 'with dummy tags enabled' do
+ context 'with tags to delete' do
let(:tags) { %w[A Ba] }
it 'deletes the tags using a dummy image' do
diff --git a/spec/views/profiles/show.html.haml_spec.rb b/spec/views/profiles/show.html.haml_spec.rb
index 592b3a56ba3..14e6feed3ab 100644
--- a/spec/views/profiles/show.html.haml_spec.rb
+++ b/spec/views/profiles/show.html.haml_spec.rb
@@ -8,6 +8,7 @@ describe 'profiles/show' do
before do
assign(:user, user)
allow(controller).to receive(:current_user).and_return(user)
+ allow(view).to receive(:experiment_enabled?)
end
context 'when the profile page is opened' do
diff --git a/vendor/aws/cloudformation/eks_cluster.yaml b/vendor/aws/cloudformation/eks_cluster.yaml
new file mode 100644
index 00000000000..ac09fc7ccca
--- /dev/null
+++ b/vendor/aws/cloudformation/eks_cluster.yaml
@@ -0,0 +1,340 @@
+---
+AWSTemplateFormatVersion: 2010-09-09
+Description: GitLab EKS Cluster
+
+Parameters:
+
+ KubernetesVersion:
+ Description: The Kubernetes version to install
+ Type: String
+ Default: 1.14
+ AllowedValues:
+ - 1.12
+ - 1.13
+ - 1.14
+
+ KeyName:
+ Description: The EC2 Key Pair to allow SSH access to the node instances
+ Type: AWS::EC2::KeyPair::KeyName
+
+ NodeImageIdSSMParam:
+ Type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>"
+ Default: /aws/service/eks/optimized-ami/1.14/amazon-linux-2/recommended/image_id
+ Description: AWS Systems Manager Parameter Store parameter of the AMI ID for the worker node instances.
+
+ NodeInstanceType:
+ Description: EC2 instance type for the node instances
+ Type: String
+ Default: t3.medium
+ ConstraintDescription: Must be a valid EC2 instance type
+ AllowedValues:
+ - t2.small
+ - t2.medium
+ - t2.large
+ - t2.xlarge
+ - t2.2xlarge
+ - t3.nano
+ - t3.micro
+ - t3.small
+ - t3.medium
+ - t3.large
+ - t3.xlarge
+ - t3.2xlarge
+ - m3.medium
+ - m3.large
+ - m3.xlarge
+ - m3.2xlarge
+ - m4.large
+ - m4.xlarge
+ - m4.2xlarge
+ - m4.4xlarge
+ - m4.10xlarge
+ - m5.large
+ - m5.xlarge
+ - m5.2xlarge
+ - m5.4xlarge
+ - m5.12xlarge
+ - m5.24xlarge
+ - c4.large
+ - c4.xlarge
+ - c4.2xlarge
+ - c4.4xlarge
+ - c4.8xlarge
+ - c5.large
+ - c5.xlarge
+ - c5.2xlarge
+ - c5.4xlarge
+ - c5.9xlarge
+ - c5.18xlarge
+ - i3.large
+ - i3.xlarge
+ - i3.2xlarge
+ - i3.4xlarge
+ - i3.8xlarge
+ - i3.16xlarge
+ - r3.xlarge
+ - r3.2xlarge
+ - r3.4xlarge
+ - r3.8xlarge
+ - r4.large
+ - r4.xlarge
+ - r4.2xlarge
+ - r4.4xlarge
+ - r4.8xlarge
+ - r4.16xlarge
+ - x1.16xlarge
+ - x1.32xlarge
+ - p2.xlarge
+ - p2.8xlarge
+ - p2.16xlarge
+ - p3.2xlarge
+ - p3.8xlarge
+ - p3.16xlarge
+ - p3dn.24xlarge
+ - r5.large
+ - r5.xlarge
+ - r5.2xlarge
+ - r5.4xlarge
+ - r5.12xlarge
+ - r5.24xlarge
+ - r5d.large
+ - r5d.xlarge
+ - r5d.2xlarge
+ - r5d.4xlarge
+ - r5d.12xlarge
+ - r5d.24xlarge
+ - z1d.large
+ - z1d.xlarge
+ - z1d.2xlarge
+ - z1d.3xlarge
+ - z1d.6xlarge
+ - z1d.12xlarge
+
+ NodeAutoScalingGroupDesiredCapacity:
+ Description: Desired capacity of Node Group ASG.
+ Type: Number
+ Default: 3
+
+ NodeVolumeSize:
+ Description: Node volume size
+ Type: Number
+ Default: 20
+
+ ClusterName:
+ Description: Unique name for your Amazon EKS cluster.
+ Type: String
+
+ ClusterRole:
+ Description: The IAM Role to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf.
+ Type: String
+
+ ClusterControlPlaneSecurityGroup:
+ Description: The security groups to apply to the EKS-managed Elastic Network Interfaces that are created in your worker node subnets.
+ Type: AWS::EC2::SecurityGroup::Id
+
+ VpcId:
+ Description: The VPC to use for your EKS Cluster resources.
+ Type: AWS::EC2::VPC::Id
+
+ Subnets:
+ Description: The subnets in your VPC where your worker nodes will run.
+ Type: List<AWS::EC2::Subnet::Id>
+
+Metadata:
+
+ AWS::CloudFormation::Interface:
+ ParameterGroups:
+ - Label:
+ default: EKS Cluster
+ Parameters:
+ - ClusterName
+ - ClusterRole
+ - KubernetesVersion
+ - ClusterControlPlaneSecurityGroup
+ - Label:
+ default: Worker Node Configuration
+ Parameters:
+ - NodeAutoScalingGroupDesiredCapacity
+ - NodeInstanceType
+ - NodeImageIdSSMParam
+ - NodeVolumeSize
+ - KeyName
+ - Label:
+ default: Worker Network Configuration
+ Parameters:
+ - VpcId
+ - Subnets
+
+Resources:
+
+ Cluster:
+ Type: AWS::EKS::Cluster
+ Properties:
+ Name: !Sub ${ClusterName}
+ Version: !Sub ${KubernetesVersion}
+ RoleArn: !Sub ${ClusterRole}
+ ResourcesVpcConfig:
+ SecurityGroupIds:
+ - !Ref ClusterControlPlaneSecurityGroup
+ SubnetIds: !Ref Subnets
+
+ NodeInstanceProfile:
+ Type: AWS::IAM::InstanceProfile
+ Properties:
+ Path: "/"
+ Roles:
+ - !Ref NodeInstanceRole
+
+ NodeInstanceRole:
+ Type: AWS::IAM::Role
+ Properties:
+ AssumeRolePolicyDocument:
+ Version: 2012-10-17
+ Statement:
+ - Effect: Allow
+ Principal:
+ Service: ec2.amazonaws.com
+ Action: sts:AssumeRole
+ Path: "/"
+ ManagedPolicyArns:
+ - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy
+ - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
+ - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
+
+ NodeSecurityGroup:
+ Type: AWS::EC2::SecurityGroup
+ Properties:
+ GroupDescription: Security group for all nodes in the cluster
+ VpcId: !Ref VpcId
+ Tags:
+ - Key: !Sub kubernetes.io/cluster/${ClusterName}
+ Value: owned
+
+ NodeSecurityGroupIngress:
+ Type: AWS::EC2::SecurityGroupIngress
+ DependsOn: NodeSecurityGroup
+ Properties:
+ Description: Allow nodes to communicate with each other
+ GroupId: !Ref NodeSecurityGroup
+ SourceSecurityGroupId: !Ref NodeSecurityGroup
+ IpProtocol: -1
+ FromPort: 0
+ ToPort: 65535
+
+ NodeSecurityGroupFromControlPlaneIngress:
+ Type: AWS::EC2::SecurityGroupIngress
+ DependsOn: NodeSecurityGroup
+ Properties:
+ Description: Allow worker Kubelets and pods to receive communication from the cluster control plane
+ GroupId: !Ref NodeSecurityGroup
+ SourceSecurityGroupId: !Ref ClusterControlPlaneSecurityGroup
+ IpProtocol: tcp
+ FromPort: 1025
+ ToPort: 65535
+
+ ControlPlaneEgressToNodeSecurityGroup:
+ Type: AWS::EC2::SecurityGroupEgress
+ DependsOn: NodeSecurityGroup
+ Properties:
+ Description: Allow the cluster control plane to communicate with worker Kubelet and pods
+ GroupId: !Ref ClusterControlPlaneSecurityGroup
+ DestinationSecurityGroupId: !Ref NodeSecurityGroup
+ IpProtocol: tcp
+ FromPort: 1025
+ ToPort: 65535
+
+ NodeSecurityGroupFromControlPlaneOn443Ingress:
+ Type: AWS::EC2::SecurityGroupIngress
+ DependsOn: NodeSecurityGroup
+ Properties:
+ Description: Allow pods running extension API servers on port 443 to receive communication from cluster control plane
+ GroupId: !Ref NodeSecurityGroup
+ SourceSecurityGroupId: !Ref ClusterControlPlaneSecurityGroup
+ IpProtocol: tcp
+ FromPort: 443
+ ToPort: 443
+
+ ControlPlaneEgressToNodeSecurityGroupOn443:
+ Type: AWS::EC2::SecurityGroupEgress
+ DependsOn: NodeSecurityGroup
+ Properties:
+ Description: Allow the cluster control plane to communicate with pods running extension API servers on port 443
+ GroupId: !Ref ClusterControlPlaneSecurityGroup
+ DestinationSecurityGroupId: !Ref NodeSecurityGroup
+ IpProtocol: tcp
+ FromPort: 443
+ ToPort: 443
+
+ ClusterControlPlaneSecurityGroupIngress:
+ Type: AWS::EC2::SecurityGroupIngress
+ DependsOn: NodeSecurityGroup
+ Properties:
+ Description: Allow pods to communicate with the cluster API Server
+ GroupId: !Ref ClusterControlPlaneSecurityGroup
+ SourceSecurityGroupId: !Ref NodeSecurityGroup
+ IpProtocol: tcp
+ ToPort: 443
+ FromPort: 443
+
+ NodeGroup:
+ Type: AWS::AutoScaling::AutoScalingGroup
+ DependsOn: Cluster
+ Properties:
+ DesiredCapacity: !Ref NodeAutoScalingGroupDesiredCapacity
+ LaunchConfigurationName: !Ref NodeLaunchConfig
+ MinSize: !Ref NodeAutoScalingGroupDesiredCapacity
+ MaxSize: !Ref NodeAutoScalingGroupDesiredCapacity
+ VPCZoneIdentifier: !Ref Subnets
+ Tags:
+ - Key: Name
+ Value: !Sub ${ClusterName}-node
+ PropagateAtLaunch: true
+ - Key: !Sub kubernetes.io/cluster/${ClusterName}
+ Value: owned
+ PropagateAtLaunch: true
+ UpdatePolicy:
+ AutoScalingRollingUpdate:
+ MaxBatchSize: 1
+ MinInstancesInService: !Ref NodeAutoScalingGroupDesiredCapacity
+ PauseTime: PT5M
+
+ NodeLaunchConfig:
+ Type: AWS::AutoScaling::LaunchConfiguration
+ Properties:
+ AssociatePublicIpAddress: true
+ IamInstanceProfile: !Ref NodeInstanceProfile
+ ImageId: !Ref NodeImageIdSSMParam
+ InstanceType: !Ref NodeInstanceType
+ KeyName: !Ref KeyName
+ SecurityGroups:
+ - !Ref NodeSecurityGroup
+ BlockDeviceMappings:
+ - DeviceName: /dev/xvda
+ Ebs:
+ VolumeSize: !Ref NodeVolumeSize
+ VolumeType: gp2
+ DeleteOnTermination: true
+ UserData:
+ Fn::Base64:
+ !Sub |
+ #!/bin/bash
+ set -o xtrace
+ /etc/eks/bootstrap.sh "${ClusterName}"
+ /opt/aws/bin/cfn-signal --exit-code $? \
+ --stack ${AWS::StackName} \
+ --resource NodeGroup \
+ --region ${AWS::Region}
+
+Outputs:
+
+ NodeInstanceRole:
+ Description: The node instance role
+ Value: !GetAtt NodeInstanceRole.Arn
+
+ ClusterCertificate:
+ Description: The cluster certificate
+ Value: !GetAtt Cluster.CertificateAuthorityData
+
+ ClusterEndpoint:
+ Description: The cluster endpoint
+ Value: !GetAtt Cluster.Endpoint