diff --git a/.rubocop_todo/gitlab/feature_available_usage.yml b/.rubocop_todo/gitlab/feature_available_usage.yml
index 38c54bf41938a35d29b726c212f79333b88b2cbe..2993409a8283cd3c5afef652349b6136a862b99c 100644
--- a/.rubocop_todo/gitlab/feature_available_usage.yml
+++ b/.rubocop_todo/gitlab/feature_available_usage.yml
@@ -27,7 +27,6 @@ Gitlab/FeatureAvailableUsage:
     - 'ee/app/helpers/ee/form_helper.rb'
     - 'ee/app/helpers/ee/graph_helper.rb'
     - 'ee/app/helpers/ee/issues_helper.rb'
-    - 'ee/app/helpers/ee/lock_helper.rb'
     - 'ee/app/helpers/ee/operations_helper.rb'
     - 'ee/app/helpers/ee/projects/incidents_helper.rb'
     - 'ee/app/helpers/ee/projects_helper.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 40e6ec8b7aa03a34b9ea813341527a3690fbb9ba..17fc374e1e4ef9d95f1d6864f2b4ce6eaac1a4f3 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -535,7 +535,6 @@ Layout/LineLength:
     - 'ee/app/helpers/ee/integrations_helper.rb'
     - 'ee/app/helpers/ee/issues_helper.rb'
     - 'ee/app/helpers/ee/labels_helper.rb'
-    - 'ee/app/helpers/ee/lock_helper.rb'
     - 'ee/app/helpers/ee/merge_requests_helper.rb'
     - 'ee/app/helpers/ee/mirror_helper.rb'
     - 'ee/app/helpers/ee/notes_helper.rb'
@@ -4209,7 +4208,6 @@ Layout/LineLength:
     - 'spec/views/projects/settings/ci_cd/_autodevops_form.html.haml_spec.rb'
     - 'spec/views/projects/settings/operations/show.html.haml_spec.rb'
     - 'spec/views/projects/tags/index.html.haml_spec.rb'
-    - 'spec/views/projects/tree/show.html.haml_spec.rb'
     - 'spec/views/shared/milestones/_issuable.html.haml_spec.rb'
     - 'spec/views/shared/projects/_project.html.haml_spec.rb'
     - 'spec/views/shared/snippets/_snippet.html.haml_spec.rb'
diff --git a/.rubocop_todo/lint/unused_method_argument.yml b/.rubocop_todo/lint/unused_method_argument.yml
index f7995c5ab54b5fa337fced26e31a3253836c64ce..d5302716428dc7c4444b218e47f1670011eb87d6 100644
--- a/.rubocop_todo/lint/unused_method_argument.yml
+++ b/.rubocop_todo/lint/unused_method_argument.yml
@@ -204,7 +204,6 @@ Lint/UnusedMethodArgument:
     - 'ee/app/graphql/types/security_orchestration/security_policy_source_type.rb'
     - 'ee/app/graphql/types/vulnerability_detail_type.rb'
     - 'ee/app/graphql/types/vulnerability_location_type.rb'
-    - 'ee/app/helpers/ee/lock_helper.rb'
     - 'ee/app/models/boards/epic_board.rb'
     - 'ee/app/models/burndown.rb'
     - 'ee/app/models/concerns/elastic/application_versioned_search.rb'
diff --git a/.rubocop_todo/rails/helper_instance_variable.yml b/.rubocop_todo/rails/helper_instance_variable.yml
index c4812f05ce4517ab9a3f0be3307fb012f28a3b6a..a72b9e70174433f0a6a8d06c81aad88112e7849f 100644
--- a/.rubocop_todo/rails/helper_instance_variable.yml
+++ b/.rubocop_todo/rails/helper_instance_variable.yml
@@ -59,7 +59,6 @@ Rails/HelperInstanceVariable:
     - 'ee/app/helpers/ee/integrations_helper.rb'
     - 'ee/app/helpers/ee/kerberos_helper.rb'
     - 'ee/app/helpers/ee/labels_helper.rb'
-    - 'ee/app/helpers/ee/lock_helper.rb'
     - 'ee/app/helpers/ee/mirror_helper.rb'
     - 'ee/app/helpers/ee/notes_helper.rb'
     - 'ee/app/helpers/ee/operations_helper.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index 9f2d6559e8185dee5c66701cf87e76f1779ca040..891abed2ca7a894c67d0a4f01edb4a19bc06f2fa 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -246,7 +246,6 @@ RSpec/ContextWording:
     - 'ee/spec/helpers/ee/groups_helper_spec.rb'
     - 'ee/spec/helpers/ee/issuables_helper_spec.rb'
     - 'ee/spec/helpers/ee/issues_helper_spec.rb'
-    - 'ee/spec/helpers/ee/lock_helper_spec.rb'
     - 'ee/spec/helpers/ee/operations_helper_spec.rb'
     - 'ee/spec/helpers/ee/personal_access_tokens_helper_spec.rb'
     - 'ee/spec/helpers/ee/projects/security/api_fuzzing_configuration_helper_spec.rb'
diff --git a/.rubocop_todo/rspec/factory_bot/avoid_create.yml b/.rubocop_todo/rspec/factory_bot/avoid_create.yml
index cd51e58ef5266881f1027400c68f2058d3d971dc..ba9d700a16dfee0e0caeaac7dd6c6655c3e1d56e 100644
--- a/.rubocop_todo/rspec/factory_bot/avoid_create.yml
+++ b/.rubocop_todo/rspec/factory_bot/avoid_create.yml
@@ -31,7 +31,6 @@ RSpec/FactoryBot/AvoidCreate:
     - 'ee/spec/helpers/ee/issuables_helper_spec.rb'
     - 'ee/spec/helpers/ee/issues_helper_spec.rb'
     - 'ee/spec/helpers/ee/labels_helper_spec.rb'
-    - 'ee/spec/helpers/ee/lock_helper_spec.rb'
     - 'ee/spec/helpers/ee/namespace_user_cap_reached_alert_helper_spec.rb'
     - 'ee/spec/helpers/ee/namespaces_helper_spec.rb'
     - 'ee/spec/helpers/ee/operations_helper_spec.rb'
@@ -585,7 +584,6 @@ RSpec/FactoryBot/AvoidCreate:
     - 'spec/views/projects/settings/merge_requests/show.html.haml_spec.rb'
     - 'spec/views/projects/settings/operations/show.html.haml_spec.rb'
     - 'spec/views/projects/tags/index.html.haml_spec.rb'
-    - 'spec/views/projects/tree/show.html.haml_spec.rb'
     - 'spec/views/search/_results.html.haml_spec.rb'
     - 'spec/views/shared/_label_row.html.haml_spec.rb'
     - 'spec/views/shared/issuable/_sidebar.html.haml_spec.rb'
diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml
index 7ceee9c6bd0f482d41c618c0ddacb42a07608c6f..48ef0e0e9d5b897e8d51a5f979e086d55ad7457f 100644
--- a/.rubocop_todo/rspec/feature_category.yml
+++ b/.rubocop_todo/rspec/feature_category.yml
@@ -363,7 +363,6 @@ RSpec/FeatureCategory:
     - 'ee/spec/helpers/ee/groups/settings_helper_spec.rb'
     - 'ee/spec/helpers/ee/hooks_helper_spec.rb'
     - 'ee/spec/helpers/ee/labels_helper_spec.rb'
-    - 'ee/spec/helpers/ee/lock_helper_spec.rb'
     - 'ee/spec/helpers/ee/namespace_user_cap_reached_alert_helper_spec.rb'
     - 'ee/spec/helpers/ee/operations_helper_spec.rb'
     - 'ee/spec/helpers/ee/profiles_helper_spec.rb'
@@ -3966,7 +3965,6 @@ RSpec/FeatureCategory:
     - 'spec/views/projects/settings/integrations/edit.html.haml_spec.rb'
     - 'spec/views/projects/settings/operations/show.html.haml_spec.rb'
     - 'spec/views/projects/tags/index.html.haml_spec.rb'
-    - 'spec/views/projects/tree/show.html.haml_spec.rb'
     - 'spec/views/shared/_label_row.html.haml_spec.rb'
     - 'spec/views/shared/_milestones_sort_dropdown.html.haml_spec.rb'
     - 'spec/views/shared/gitlab_version/_security_patch_upgrade_alert.html.haml_spec.rb'
diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml
index 75ecde8c27d8238b14588825ed0ff4cb4a84ff06..22ee999caad96f4b789fecbe53ffc21a29e0631b 100644
--- a/.rubocop_todo/rspec/named_subject.yml
+++ b/.rubocop_todo/rspec/named_subject.yml
@@ -184,7 +184,6 @@ RSpec/NamedSubject:
     - 'ee/spec/helpers/ee/gitlab_routing_helper_spec.rb'
     - 'ee/spec/helpers/ee/groups/group_members_helper_spec.rb'
     - 'ee/spec/helpers/ee/groups_helper_spec.rb'
-    - 'ee/spec/helpers/ee/lock_helper_spec.rb'
     - 'ee/spec/helpers/ee/merge_requests_helper_spec.rb'
     - 'ee/spec/helpers/ee/operations_helper_spec.rb'
     - 'ee/spec/helpers/ee/projects/incidents_helper_spec.rb'
diff --git a/.rubocop_todo/rspec/receive_messages.yml b/.rubocop_todo/rspec/receive_messages.yml
index 581c114c0d1d6cd9af745a3904526202aaec2492..1f635a419676180514b9c85a4c5f45cb8612bf15 100644
--- a/.rubocop_todo/rspec/receive_messages.yml
+++ b/.rubocop_todo/rspec/receive_messages.yml
@@ -25,7 +25,6 @@ RSpec/ReceiveMessages:
     - 'ee/spec/helpers/ee/ide_helper_spec.rb'
     - 'ee/spec/helpers/ee/issuables_helper_spec.rb'
     - 'ee/spec/helpers/ee/issues_helper_spec.rb'
-    - 'ee/spec/helpers/ee/lock_helper_spec.rb'
     - 'ee/spec/helpers/ee/namespaces_helper_spec.rb'
     - 'ee/spec/helpers/ee/registrations_helper_spec.rb'
     - 'ee/spec/helpers/ee/subscribable_banner_helper_spec.rb'
@@ -571,7 +570,6 @@ RSpec/ReceiveMessages:
     - 'spec/views/projects/settings/operations/show.html.haml_spec.rb'
     - 'spec/views/projects/settings/repository/_protected_branches.html.haml_spec.rb'
     - 'spec/views/projects/tags/index.html.haml_spec.rb'
-    - 'spec/views/projects/tree/show.html.haml_spec.rb'
     - 'spec/views/shared/_broadcast_message.html.haml_spec.rb'
     - 'spec/views/shared/projects/_list.html.haml_spec.rb'
     - 'spec/views/shared/projects/_project_card.html.haml_spec.rb'
diff --git a/.rubocop_todo/rspec/subject_declaration.yml b/.rubocop_todo/rspec/subject_declaration.yml
index 052605f94d5cb7f5e69162bf60632f1ed15b8315..ec46ac41a7a1f153db1afe82adfadcf84c97a309 100644
--- a/.rubocop_todo/rspec/subject_declaration.yml
+++ b/.rubocop_todo/rspec/subject_declaration.yml
@@ -2,7 +2,6 @@
 RSpec/SubjectDeclaration:
   Exclude:
     - 'ee/spec/finders/app_sec/fuzzing/coverage/corpuses_finder_spec.rb'
-    - 'ee/spec/helpers/ee/lock_helper_spec.rb'
     - 'ee/spec/helpers/nav/new_dropdown_helper_spec.rb'
     - 'ee/spec/lib/ee/api/helpers/notes_helpers_spec.rb'
     - 'ee/spec/lib/gitlab/expiring_subscription_message_spec.rb'
diff --git a/app/assets/javascripts/pages/projects/show/index.js b/app/assets/javascripts/pages/projects/show/index.js
index 16956a51b0ea6b20a1c2b4d1bbe1e1df0807b7ef..074eafce2272802b200d5dcbd4fd3b83eb766ab8 100644
--- a/app/assets/javascripts/pages/projects/show/index.js
+++ b/app/assets/javascripts/pages/projects/show/index.js
@@ -72,10 +72,9 @@ const initCodeDropdown = () => {
 
   const { sshUrl, httpUrl, kerberosUrl } = codeDropdownEl.dataset;
 
-  const CodeDropdownComponent =
-    gon.features.directoryCodeDropdownUpdates && gon.features.blobRepositoryVueHeaderApp
-      ? CompactCodeDropdown
-      : CodeDropdown;
+  const CodeDropdownComponent = gon.features.directoryCodeDropdownUpdates
+    ? CompactCodeDropdown
+    : CodeDropdown;
 
   return new Vue({
     el: codeDropdownEl,
diff --git a/app/assets/javascripts/repository/components/header_area.vue b/app/assets/javascripts/repository/components/header_area.vue
index 93c8481a3b75489458aad31731cd7358af13533e..b000dc8cf0aad1737dbf5edd1291797b3925a68e 100644
--- a/app/assets/javascripts/repository/components/header_area.vue
+++ b/app/assets/javascripts/repository/components/header_area.vue
@@ -265,7 +265,7 @@ export default {
           :upload-path="uploadPath"
           :new-dir-path="newDirPath"
         />
-        <!-- EE: = render_if_exists 'projects/tree/lock_link' -->
+        <!-- EE lock directory -->
         <lock-directory-button v-if="!isRoot" :project-path="projectPath" :path="currentPath" />
         <gl-button
           v-gl-tooltip.html="findFileTooltip"
diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js
index 7b5c975ddfe4270693d510c5fb73b0ba5f1f30f4..3a809c520843b0cb8c10d1e356ad7d29626446c7 100644
--- a/app/assets/javascripts/repository/index.js
+++ b/app/assets/javascripts/repository/index.js
@@ -188,10 +188,9 @@ export default function setupVueRepositoryList() {
     const { sshUrl, httpUrl, kerberosUrl, xcodeUrl, directoryDownloadLinks } =
       codeDropdownEl.dataset;
 
-    const CodeDropdownComponent =
-      gon.features.directoryCodeDropdownUpdates && gon.features.blobRepositoryVueHeaderApp
-        ? CompactCodeDropdown
-        : CodeDropdown;
+    const CodeDropdownComponent = gon.features.directoryCodeDropdownUpdates
+      ? CompactCodeDropdown
+      : CodeDropdown;
 
     return new Vue({
       el: codeDropdownEl,
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 4ef92f34ea6ed576e91ff74406d27bd4bc376b9c..7feaf58246289ed519aaed5aa1ad3f8963496bc4 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -47,7 +47,6 @@ class Projects::BlobController < Projects::ApplicationController
     push_frontend_feature_flag(:inline_blame, @project)
     push_frontend_feature_flag(:blob_overflow_menu, current_user)
     push_frontend_feature_flag(:filter_blob_path, current_user)
-    push_frontend_feature_flag(:blob_repository_vue_header_app, @project)
     push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
     push_frontend_feature_flag(:directory_code_dropdown_updates, current_user)
   end
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index f4a93d03fa3c422e5f5674cb28b647a05ed18c6c..8fbf44e58f9e6af2a67600c6df03e3cf10c37e21 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -19,7 +19,6 @@ class Projects::TreeController < Projects::ApplicationController
 
   before_action do
     push_frontend_feature_flag(:inline_blame, @project)
-    push_frontend_feature_flag(:blob_repository_vue_header_app, @project)
     push_frontend_feature_flag(:blob_overflow_menu, current_user)
     push_frontend_feature_flag(:filter_blob_path, current_user)
     push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 99a3e9f2725ca2cdcd0c0b95e4b65498db89a4ef..0f4784cbdd0d51691fdd1dbd6b70b2739a25dbbf 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -42,7 +42,6 @@ class ProjectsController < Projects::ApplicationController
     push_frontend_feature_flag(:edit_branch_rules, @project)
     # TODO: We need to remove the FF eventually when we rollout page_specific_styles
     push_frontend_feature_flag(:page_specific_styles, current_user)
-    push_frontend_feature_flag(:blob_repository_vue_header_app, @project)
     push_frontend_feature_flag(:blob_overflow_menu, current_user)
     push_frontend_feature_flag(:filter_blob_path, current_user)
     push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml
index 5cf20ac8931088b83eb39eccca6cad853d610a0e..c0751180a5370ef203b2e1e0936d822db221f794 100644
--- a/app/views/projects/_files.html.haml
+++ b/app/views/projects/_files.html.haml
@@ -8,12 +8,7 @@
 - add_page_specific_style 'page_bundles/projects'
 
 #tree-holder.tree-holder.clearfix.js-per-page.gl-mt-5{ data: { blame_per_page: Gitlab::Git::BlamePagination::PAGINATION_PER_PAGE } }
-  - if Feature.enabled?(:blob_repository_vue_header_app, project)
-    #js-repository-blob-header-app{ data: vue_tree_header_app_data(project, repository, ref, pipeline) }
-
-  - else
-    .nav-block.gl-flex.gl-flex-col.sm:gl-flex-row.gl-items-stretch
-      = render 'projects/tree/tree_header', tree: @tree
+  #js-repository-blob-header-app{ data: vue_tree_header_app_data(project, repository, ref, pipeline) }
 
   - if project.forked?
     #js-fork-info{ data: vue_fork_divergence_data(project, ref) }
diff --git a/app/views/projects/_readme.html.haml b/app/views/projects/_readme.html.haml
index f62667206ccfc926f05059fd821f61b21431bed7..664b036519efd5469db75d6964472f464454ea4a 100644
--- a/app/views/projects/_readme.html.haml
+++ b/app/views/projects/_readme.html.haml
@@ -8,23 +8,18 @@
 
 - if (readme = @repository.readme) && readme.rich_viewer
   .tree-holder.gl-mt-5
-    - if Feature.enabled?(:blob_repository_vue_header_app, project)
-      #js-repository-blob-header-app{ data: {
-        project_id: @project.id,
-        ref: ref,
-        ref_type: @ref_type.to_s,
-        breadcrumbs: breadcrumb_data_attributes,
-        project_root_path: project_path(@project),
-        project_path: project.full_path,
-        compare_path: compare_path,
-        web_ide_button_options: web_ide_button_data.merge(fork_options).to_json,
-        web_ide_button_default_branch: @project.default_branch_or_main,
-        escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref)
-      } }
-
-    - else
-      .nav-block.mt-0
-        = render 'projects/tree/tree_header', tree: @tree
+    #js-repository-blob-header-app{ data: {
+      project_id: @project.id,
+      ref: ref,
+      ref_type: @ref_type.to_s,
+      breadcrumbs: breadcrumb_data_attributes,
+      project_root_path: project_path(@project),
+      project_path: project.full_path,
+      compare_path: compare_path,
+      web_ide_button_options: web_ide_button_data.merge(fork_options).to_json,
+      web_ide_button_default_branch: @project.default_branch_or_main,
+      escaped_ref: ActionDispatch::Journey::Router::Utils.escape_path(ref)
+    } }
 
   %article.file-holder.readme-holder{ id: 'readme', class: ("limited-width-container" unless fluid_layout) }
     .js-file-title.file-title-flex-parent
diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml
index 4e91e31674fd1de39d6ec47c4b55021be33f5785..ee9d2fe73e1a68ce4a274c5826fb4d2a7fe92c9b 100644
--- a/app/views/projects/blob/_blob.html.haml
+++ b/app/views/projects/blob/_blob.html.haml
@@ -6,10 +6,7 @@
 - if blob.rich_viewer && blob.extension != 'geojson'
   - add_page_startup_api_call local_assigns.fetch(:viewer_url) { url_for(safe_params.merge(viewer: blob.rich_viewer.type, format: :json)) }
 
-- if Feature.enabled?(:blob_repository_vue_header_app, project)
-  #js-repository-blob-header-app{ data: vue_blob_header_app_data(project, blob, ref) }
-- else
-  = render "projects/blob/breadcrumb", blob: blob
+#js-repository-blob-header-app{ data: vue_blob_header_app_data(project, blob, ref) }
 
 - if project.forked?
   #js-fork-info{ data: vue_fork_divergence_data(project, ref) }
diff --git a/app/views/projects/buttons/_compare.html.haml b/app/views/projects/buttons/_compare.html.haml
deleted file mode 100644
index 82b1b837fbb9fda0222f9f1722d4a0c8eb2f8963..0000000000000000000000000000000000000000
--- a/app/views/projects/buttons/_compare.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-- project = local_assigns.fetch(:project)
-- ref = local_assigns.fetch(:ref, nil)
-- root_ref = local_assigns.fetch(:root_ref, nil)
-- unless ref.blank? || root_ref == ref
-  - compare_path = project_compare_index_path(project, from: root_ref, to: ref)
-
-  = link_button_to compare_path, class: 'shortcuts-compare', rel: 'nofollow' do
-    = _('Compare')
diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml
deleted file mode 100644
index 8d353c4c4a76bde5362e43dcc992447916b764e1..0000000000000000000000000000000000000000
--- a/app/views/projects/tree/_tree_header.html.haml
+++ /dev/null
@@ -1,21 +0,0 @@
-.tree-ref-container.gl-flex.gl-flex-wrap.gl-gap-2.mb-2.mb-md-0
-  .tree-ref-holder.gl-max-w-26{ data: { testid: 'ref-dropdown-container' } }
-    #js-tree-ref-switcher{ data: { project_id: @project.id, ref_type: @ref_type.to_s, project_root_path: project_path(@project) } }
-
-  #js-repo-breadcrumb{ data: breadcrumb_data_attributes }
-
-#js-blob-controls
-.tree-controls
-  .gl-flex.gl-flex-wrap.gl-gap-3.gl-mb-3.sm:gl-mb-0
-    = render_if_exists 'projects/tree/lock_link'
-    = render 'projects/buttons/compare', project: @project, ref: @ref, root_ref: @repository&.root_ref
-
-    = render 'projects/find_file_link'
-    = render 'shared/web_ide_button', blob: nil, css_classes: 'gl-w-full sm:gl-w-auto'
-
-    .project-code-holder.gl-hidden.sm:gl-inline-block
-      = render "projects/buttons/code", dropdown_class: 'dropdown-menu-right', ref: @ref
-
-  .project-code-holder.gl-flex.gl-gap-3{ class: 'sm:!gl-hidden' }
-    = render 'projects/buttons/download', project: @project, ref: @ref
-    = render "shared/mobile_clone_panel", ref: @ref
diff --git a/config/feature_flags/gitlab_com_derisk/blob_repository_vue_header_app.yml b/config/feature_flags/gitlab_com_derisk/blob_repository_vue_header_app.yml
deleted file mode 100644
index dbe3028f77915151b7439df0beb22ca0d674c0cb..0000000000000000000000000000000000000000
--- a/config/feature_flags/gitlab_com_derisk/blob_repository_vue_header_app.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-name: blob_repository_vue_header_app
-feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/509327
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176182
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/513582
-milestone: '17.9'
-group: group::source code
-type: gitlab_com_derisk
-default_enabled: false
diff --git a/ee/app/assets/javascripts/repository/index.js b/ee/app/assets/javascripts/repository/index.js
index 82ce2a5231f1a4217f97f6868ee3931f41e01ad3..b25fd6c9a539b5cddcd957697faef41b5d69d6dd 100644
--- a/ee/app/assets/javascripts/repository/index.js
+++ b/ee/app/assets/javascripts/repository/index.js
@@ -1,45 +1,7 @@
 import Vue from 'vue';
-import { createAlert } from '~/alert';
-import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
-import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
 import initTree from '~/repository';
 import CodeOwners from '../vue_shared/components/code_owners/code_owners.vue';
 
-const initPathLocks = (data, router) => {
-  if (data.pathLocksAvailable) {
-    const toggleBtn = document.querySelector('a.js-path-lock');
-    if (!toggleBtn) return;
-
-    toggleBtn.addEventListener('click', async (e) => {
-      e.preventDefault();
-
-      const { dataset } = e.currentTarget;
-      const message =
-        dataset.state === 'lock'
-          ? __('Are you sure you want to lock this directory?')
-          : __('Are you sure you want to unlock this directory?');
-
-      const confirmed = await confirmAction(message);
-      if (!confirmed) return;
-
-      toggleBtn.setAttribute('disabled', 'disabled');
-
-      axios
-        .post(data.pathLocksToggle, {
-          path: router.currentRoute.params.path.replace(/^\//, ''),
-        })
-        .then(() => window.location.reload())
-        .catch(() => {
-          toggleBtn.removeAttribute('disabled');
-          createAlert({
-            message: __('An error occurred while initializing path locks'),
-          });
-        });
-    });
-  }
-};
-
 const initCodeOwnersApp = (router, apolloProvider, projectPath) => {
   const codeOwnersEl = document.querySelector('#js-code-owners');
   if (!codeOwnersEl) return null;
@@ -64,10 +26,7 @@ const initCodeOwnersApp = (router, apolloProvider, projectPath) => {
 };
 
 export default () => {
-  const { router, data, apolloProvider, projectPath } = initTree();
+  const { router, apolloProvider, projectPath } = initTree();
 
-  if (!gon.features.blobRepositoryVueHeaderApp) {
-    initPathLocks(data, router);
-  }
   initCodeOwnersApp(router, apolloProvider, projectPath);
 };
diff --git a/ee/app/helpers/ee/lock_helper.rb b/ee/app/helpers/ee/lock_helper.rb
deleted file mode 100644
index e5abdfc31453618802acea04bc48141ca8ef2e46..0000000000000000000000000000000000000000
--- a/ee/app/helpers/ee/lock_helper.rb
+++ /dev/null
@@ -1,72 +0,0 @@
-# frozen_string_literal: true
-
-module EE
-  module LockHelper
-    DEFAULT_CSS_CLASSES = 'path-lock js-path-lock js-hide-on-root hidden'
-
-    def lock_file_link(project = @project, path = @path)
-      return unless project.feature_available?(:file_locks)
-      return unless current_user
-
-      path_lock = project.find_path_lock(path, downstream: true)
-
-      if path_lock
-        locker = path_lock.user.name
-
-        if path_lock.exact?(path)
-          exact_lock_file_link(path_lock, locker)
-        elsif path_lock.upstream?(path)
-          upstream_lock_file_link(path_lock, locker)
-        elsif path_lock.downstream?(path)
-          downstream_lock_file_link(path_lock, locker)
-        end
-      else
-        _lock_link(current_user, project)
-      end
-    end
-
-    private
-
-    def exact_lock_file_link(path_lock, locker)
-      if can_unlock?(path_lock)
-        tooltip = path_lock.user == current_user ? '' : "Locked by #{locker}"
-        enabled_lock_link("Unlock", tooltip, :unlock)
-      else
-        disabled_lock_link("Unlock", "Locked by #{locker}. You do not have permission to unlock this")
-      end
-    end
-
-    def upstream_lock_file_link(path_lock, locker)
-      additional_phrase = can_unlock?(path_lock) ? 'Unlock that directory in order to unlock this' : 'You do not have permission to unlock it'
-      disabled_lock_link("Unlock", "#{locker} has a lock on \"#{path_lock.path}\". #{additional_phrase}")
-    end
-
-    def downstream_lock_file_link(path_lock, locker)
-      additional_phrase = can_unlock?(path_lock) ? 'Unlock this in order to proceed' : 'You do not have permission to unlock it'
-      disabled_lock_link("Lock", "This directory cannot be locked while #{locker} has a lock on \"#{path_lock.path}\". #{additional_phrase}")
-    end
-
-    def _lock_link(user, project)
-      if can?(current_user, :push_code, project)
-        enabled_lock_link("Lock", '', :lock)
-      else
-        disabled_lock_link("Lock", "You do not have permission to lock this")
-      end
-    end
-
-    def disabled_lock_link(label, title)
-      # Disabled buttons with tooltips should have the tooltip attached
-      # to a wrapper element https://bootstrap-vue.org/docs/components/tooltip#disabled-elements
-      button = render Pajamas::ButtonComponent.new(disabled: true, button_options: { class: DEFAULT_CSS_CLASSES, data: { testid: 'disabled-lock-button' } }) do
-        label
-      end
-      content_tag(:span, button, title: title, class: 'btn-group has-tooltip')
-    end
-
-    def enabled_lock_link(label, title, state)
-      render Pajamas::ButtonComponent.new(href: '#', button_options: { class: "#{DEFAULT_CSS_CLASSES} has-tooltip", title: title, data: { state: state, toggle: 'tooltip', testid: 'lock-button' } }) do
-        label
-      end
-    end
-  end
-end
diff --git a/ee/app/views/projects/tree/_lock_link.html.haml b/ee/app/views/projects/tree/_lock_link.html.haml
deleted file mode 100644
index fe03d7db3675fb0fb547bf0c1ec040198fd23825..0000000000000000000000000000000000000000
--- a/ee/app/views/projects/tree/_lock_link.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-= lock_file_link
diff --git a/ee/spec/helpers/ee/lock_helper_spec.rb b/ee/spec/helpers/ee/lock_helper_spec.rb
deleted file mode 100644
index 89dcb59dec9a91bebdfb427ded383df69563194c..0000000000000000000000000000000000000000
--- a/ee/spec/helpers/ee/lock_helper_spec.rb
+++ /dev/null
@@ -1,136 +0,0 @@
-# frozen_string_literal: true
-
-require "spec_helper"
-
-RSpec.describe EE::LockHelper do
-  describe '#lock_file_link' do
-    let!(:path_lock) { create :path_lock, path: 'app/models' }
-    let(:path) { path_lock.path }
-    let(:user) { path_lock.user }
-    let(:project) { path_lock.project }
-    let_it_be(:disabled_attr) { 'disabled="disabled"' }
-
-    before do
-      allow(helper).to receive(:can?).and_return(true)
-      allow(helper).to receive(:current_user).and_return(user)
-      allow(project).to receive(:feature_available?).with(:file_locks).and_return(true)
-
-      project.reload
-    end
-
-    context 'when there is no lock' do
-      let(:subject) { helper.lock_file_link(project, '.gitignore') }
-      let_it_be(:tooltip_text) { "You do not have permission to lock this" }
-
-      context 'when user can push code to the project' do
-        it 'returns an enabled "Lock" button without a tooltip' do
-          expect(subject).to match('Lock')
-          expect(subject).not_to match(disabled_attr)
-          expect(subject).not_to match(tooltip_text)
-        end
-      end
-
-      context 'when user cannot push code to the project' do
-        before do
-          allow(helper).to receive(:can?).and_return(false)
-        end
-
-        it 'returns a disabled "Lock" button with a tooltip' do
-          expect(subject).to match('Lock')
-          expect(subject).to match(disabled_attr)
-          expect(subject).to match(tooltip_text)
-        end
-      end
-    end
-
-    context 'when there is no conflicting lock' do
-      let(:subject) { helper.lock_file_link(project, path) }
-      let_it_be(:tooltip_text) { "Locked by" }
-
-      context 'when user is allowed to unlock the path' do
-        context 'when path was locked by the current user' do
-          it 'returns an enabled "Unlock" button without a tooltip' do
-            expect(subject).to match('Unlock')
-            expect(subject).not_to match(disabled_attr)
-            expect(subject).not_to match(tooltip_text)
-          end
-        end
-
-        context 'wnen path was locked by someone else' do
-          let(:user2) { create :user }
-
-          before do
-            allow(helper).to receive(:current_user).and_return(user2)
-          end
-
-          it 'returns an enabled "Unlock" button with a tooltip' do
-            expect(subject).to match('Unlock')
-            expect(subject).not_to match(disabled_attr)
-            expect(subject).to match(tooltip_text)
-          end
-        end
-      end
-
-      context 'when user is not allowed to unlock the path' do
-        before do
-          allow(helper).to receive(:can?).and_return(false)
-        end
-
-        it 'returns a disabled "Unlock" button with a tooltip' do
-          expect(subject).to match('Unlock')
-          expect(subject).to match(disabled_attr)
-          expect(subject).to match(tooltip_text)
-        end
-      end
-    end
-
-    context 'when there is an upstream lock' do
-      let(:requested_path) { 'app/models/user.rb' }
-      let(:subject) { helper.lock_file_link(project, requested_path) }
-
-      context 'when user is allowed to unlock the upstream path' do
-        it 'returns a disabled "Unlock" button with a tooltip' do
-          expect(subject).to match('Unlock')
-          expect(subject).to match(disabled_attr)
-          expect(subject).to match("Unlock that directory in order to unlock this")
-        end
-      end
-
-      context 'when user is not allowed to unlock the upstream path' do
-        before do
-          allow(helper).to receive(:can?).and_return(false)
-        end
-
-        it 'returns a disabled "Unlock" button with a tooltip' do
-          expect(subject).to match('Unlock')
-          expect(subject).to match(disabled_attr)
-          expect(subject).to match("You do not have permission to unlock it")
-        end
-      end
-    end
-
-    context 'when there is a downstream lock' do
-      let(:subject) { helper.lock_file_link(project, 'app') }
-
-      context 'when user is allowed to unlock the downstream path' do
-        it 'returns a disabled "Lock" button with a tooltip' do
-          expect(subject).to match('Lock')
-          expect(subject).to match(disabled_attr)
-          expect(subject).to match("Unlock this in order to proceed")
-        end
-      end
-
-      context 'when user is not allowed to unlock the downstream path' do
-        before do
-          allow(helper).to receive(:can?).and_return(false)
-        end
-
-        it 'returns a disabled "Lock" button with a tooltip' do
-          expect(subject).to match('Lock')
-          expect(subject).to match(disabled_attr)
-          expect(subject).to match("You do not have permission to unlock it")
-        end
-      end
-    end
-  end
-end
diff --git a/spec/frontend/repository/components/header_area_spec.js b/spec/frontend/repository/components/header_area_spec.js
index 6f68c509cc34f3e78d264236fd5a489686afedce..2f959786fc559f44b6b994cd05b4384781388da8 100644
--- a/spec/frontend/repository/components/header_area_spec.js
+++ b/spec/frontend/repository/components/header_area_spec.js
@@ -80,8 +80,15 @@ describe('HeaderArea', () => {
     expect(wrapper.exists()).toBe(true);
   });
 
-  it('renders RefSelector', () => {
-    expect(findRefSelector().exists()).toBe(true);
+  describe('Ref selector', () => {
+    it('renders correctly', () => {
+      expect(findRefSelector().exists()).toBe(true);
+    });
+
+    it('renders correctly when branch names ending with .json', () => {
+      createComponent({ props: { refSelectorValue: 'ends-with.json' } });
+      expect(findRefSelector().exists()).toBe(true);
+    });
   });
 
   it('renders Breadcrumbs component', () => {
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index 06b2553da71342f8063a2e21e8ae24e673908bed..d6fef67dc9c82a8679dc70610cf1dca5e9831aac 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -665,7 +665,6 @@
 - './ee/spec/helpers/ee/issuables_helper_spec.rb'
 - './ee/spec/helpers/ee/issues_helper_spec.rb'
 - './ee/spec/helpers/ee/labels_helper_spec.rb'
-- './ee/spec/helpers/ee/lock_helper_spec.rb'
 - './ee/spec/helpers/ee/namespaces_helper_spec.rb'
 - './ee/spec/helpers/ee/namespace_user_cap_reached_alert_helper_spec.rb'
 - './ee/spec/helpers/ee/operations_helper_spec.rb'
diff --git a/spec/views/projects/tree/show.html.haml_spec.rb b/spec/views/projects/tree/show.html.haml_spec.rb
deleted file mode 100644
index 4e77173d31183a703b2566ef63d739f8ab1bfce0..0000000000000000000000000000000000000000
--- a/spec/views/projects/tree/show.html.haml_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'projects/tree/show' do
-  include Devise::Test::ControllerHelpers
-
-  let_it_be(:project) { create(:project, :repository, create_branch: 'bar') }
-  let(:repository) { project.repository }
-  let(:ref) { 'master' }
-  let(:commit) { repository.commit(ref) }
-  let(:path) { '' }
-  let(:tree) { repository.tree(commit.id, path) }
-
-  before do
-    stub_feature_flags(blob_repository_vue_header_app: false)
-    assign(:project, project)
-    assign(:repository, repository)
-
-    allow(view).to receive(:can?).and_return(true)
-    allow(view).to receive(:can_collaborate_with_project?).and_return(true)
-    allow(view).to receive_message_chain('user_access.can_push_to_branch?').and_return(true)
-    allow(view).to receive(:current_application_settings).and_return(Gitlab::CurrentSettings.current_application_settings)
-    allow(view).to receive(:current_user).and_return(project.creator)
-
-    assign(:id, File.join(ref, path))
-    assign(:ref, ref)
-    assign(:path, path)
-    assign(:last_commit, commit)
-    assign(:tree, tree)
-  end
-
-  context 'for branch names ending on .json' do
-    let(:ref) { 'ends-with.json' }
-
-    it 'displays correctly' do
-      render
-
-      expect(rendered).to have_css('#js-tree-ref-switcher')
-    end
-  end
-
-  context 'when on root ref' do
-    let(:ref) { repository.root_ref }
-
-    it 'hides compare button' do
-      render
-
-      expect(rendered).not_to include('Compare')
-    end
-  end
-
-  context 'when not on root ref' do
-    let(:ref) { 'bar' }
-
-    it 'shows a compare button' do
-      render
-
-      expect(rendered).to include('Compare')
-    end
-  end
-end