diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1862eb527ea40d2d99e7dceb2c7b2d779c38e527..4a53bd70c295d9bcfe2a6983eaad1f6bad10dad6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -313,7 +313,7 @@ flaky-examples-check:
     - scripts/merge-reports ${NEW_FLAKY_SPECS_REPORT} rspec_flaky/new_*_*.json
     - scripts/detect-new-flaky-examples $NEW_FLAKY_SPECS_REPORT
 
-setup-test-env:
+compile-assets:
   <<: *dedicated-runner
   <<: *except-docs
   <<: *use-pg
@@ -324,13 +324,25 @@ setup-test-env:
     - node --version
     - yarn install --frozen-lockfile --cache-folder .yarn-cache
     - bundle exec rake gitlab:assets:compile
-    - bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
-    - scripts/gitaly-test-build # Do not use 'bundle exec' here
   artifacts:
     expire_in: 7d
     paths:
       - node_modules
       - public/assets
+
+setup-test-env:
+  <<: *dedicated-runner
+  <<: *except-docs
+  <<: *use-pg
+  stage: prepare
+  cache:
+    <<: *default-cache
+  script:
+    - bundle exec ruby -Ispec -e 'require "spec_helper" ; TestEnv.init'
+    - scripts/gitaly-test-build # Do not use 'bundle exec' here
+  artifacts:
+    expire_in: 7d
+    paths:
       - tmp/tests
 
 rspec-pg geo: *rspec-metadata-pg-geo
@@ -689,6 +701,7 @@ lint:javascript:report:
   <<: *pull-cache
   stage: post-test
   dependencies:
+    - compile-assets
     - setup-test-env
   before_script: []
   script:
diff --git a/app/assets/stylesheets/framework/layout.scss b/app/assets/stylesheets/framework/layout.scss
index fab3270b9f52e949bca902cf8aaca53d8b85e7e4..d107422e5176d1290867fae3bc1a4a0b19ae821e 100644
--- a/app/assets/stylesheets/framework/layout.scss
+++ b/app/assets/stylesheets/framework/layout.scss
@@ -1,10 +1,16 @@
 html {
   overflow-y: scroll;
 
-  &.touch .tooltip { display: none !important; }
+  &.touch .tooltip {
+    display: none !important;
+  }
 }
 
 body {
+  // Improves readability for dyslexic users; supported only in Chrome/Safari so far
+  // scss-lint:disable PropertySpelling
+  text-decoration-skip: ink;
+  // scss-lint:enable PropertySpelling
   &.navless {
     background-color: $white-light !important;
   }
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 2d09816edd8497d4fd3fbd5dc71b81e4f8e1d755..ad3b43bb606776d3a63b4083b9ad3f190b27d870 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -202,6 +202,7 @@ module ApplicationSettingsHelper
       :metrics_sample_interval,
       :metrics_timeout,
       :password_authentication_enabled_for_web,
+      :password_authentication_enabled_for_git,
       :performance_bar_allowed_group_id,
       :performance_bar_enabled,
       :plantuml_enabled,
diff --git a/app/models/project.rb b/app/models/project.rb
index e7e84a0bf98f0d70479a53acfbbe8be5ec59733f..d726316707bcea488787e09bb6f539234f0d201b 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1449,7 +1449,7 @@ class Project < ActiveRecord::Base
     # We'd need to keep track of project full path otherwise directory tree
     # created with hashed storage enabled cannot be usefully imported using
     # the import rake task.
-    repository.rugged.config['gitlab.fullpath'] = gl_full_path
+    repository.raw_repository.write_config(full_path: gl_full_path)
   rescue Gitlab::Git::Repository::NoRepository => e
     Rails.logger.error("Error writing to .git/config for project #{full_path} (#{id}): #{e.message}.")
     nil
diff --git a/changelogs/unreleased/41814-text-decoration-skip.yml b/changelogs/unreleased/41814-text-decoration-skip.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3e39d26be932e9ed6ada663edb4703cf188ace4c
--- /dev/null
+++ b/changelogs/unreleased/41814-text-decoration-skip.yml
@@ -0,0 +1,5 @@
+---
+title: Improve readability of underlined links for dyslexic users
+merge_request:
+author:
+type: other
diff --git a/changelogs/unreleased/42206-permit-password-for-git-param.yml b/changelogs/unreleased/42206-permit-password-for-git-param.yml
new file mode 100644
index 0000000000000000000000000000000000000000..563dd528ad52e8806937d3f3b141789880e74c0f
--- /dev/null
+++ b/changelogs/unreleased/42206-permit-password-for-git-param.yml
@@ -0,0 +1,5 @@
+---
+title: Permits 'password_authentication_enabled_for_git' parameter for ApplicationSettingsController
+merge_request:
+author:
+type: fixed
diff --git a/changelogs/unreleased/42231-protected-branches-api-route-returns-404-for-branches-with-dots.yml b/changelogs/unreleased/42231-protected-branches-api-route-returns-404-for-branches-with-dots.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fbc589ea53db307381b470a9f9704f8d887da6bc
--- /dev/null
+++ b/changelogs/unreleased/42231-protected-branches-api-route-returns-404-for-branches-with-dots.yml
@@ -0,0 +1,5 @@
+---
+title: Fix protected branches API to accept name parameter with dot
+merge_request:
+author:
+type: fixed
diff --git a/lib/api/protected_branches.rb b/lib/api/protected_branches.rb
index 6685d84adeb01a9e8a5d7d4dfa36d83a3ec1b3dc..856a04baf2faa7ca9d9f23a31792d548ad75583e 100644
--- a/lib/api/protected_branches.rb
+++ b/lib/api/protected_branches.rb
@@ -2,7 +2,7 @@ module API
   class ProtectedBranches < Grape::API
     include PaginationParams
 
-    BRANCH_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(branch: API::NO_SLASH_URL_PART_REGEX)
+    BRANCH_ENDPOINT_REQUIREMENTS = API::PROJECT_ENDPOINT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX)
 
     before { authorize_admin_project }
 
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index e1b0085d03bd30f702e664be709f6d703cb6bcc6..f8fec569c1bef8abf2a5cfb3ef09b47f16b53c5c 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -1311,6 +1311,10 @@ module Gitlab
       end
       # rubocop:enable Metrics/ParameterLists
 
+      def write_config(full_path:)
+        rugged.config['gitlab.fullpath'] = full_path if full_path.present?
+      end
+
       def gitaly_repository
         Gitlab::GitalyClient::Util.repository(@storage, @relative_path, @gl_repository)
       end
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index ba9497a32827359d481795ea3c540d5e6c9b7379..5cc5e8fdbb121b586266cd7450f20698b35485a5 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -51,6 +51,13 @@ describe Admin::ApplicationSettingsController do
       sign_in(admin)
     end
 
+    it 'updates the password_authentication_enabled_for_git setting' do
+      put :update, application_setting: { password_authentication_enabled_for_git: "0" }
+
+      expect(response).to redirect_to(admin_application_settings_path)
+      expect(ApplicationSetting.current.password_authentication_enabled_for_git).to eq(false)
+    end
+
     it 'updates the default_project_visibility for string value' do
       put :update, application_setting: { default_project_visibility: "20" }
 
diff --git a/spec/requests/api/protected_branches_spec.rb b/spec/requests/api/protected_branches_spec.rb
index 8bb4fd5febd4a2a6906b196cd01fa53f10a3b3d6..ab0bb92778bf1e32ecb1faedb7e7d74975ae0f9d 100644
--- a/spec/requests/api/protected_branches_spec.rb
+++ b/spec/requests/api/protected_branches_spec.rb
@@ -101,6 +101,12 @@ describe API::ProtectedBranches do
 
         it_behaves_like 'protected branch'
       end
+
+      context 'when protected branch contains a period' do
+        let(:protected_name) { 'my.feature' }
+
+        it_behaves_like 'protected branch'
+      end
     end
 
     context 'when authenticated as a guest' do
diff --git a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
index eec356b9f47ebe60d20a906a17b9206690442858..5ebad58e1714e82d6dff0c32231c94653cc755e3 100644
--- a/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
+++ b/vendor/gitlab-ci-yml/Auto-DevOps.gitlab-ci.yml
@@ -42,6 +42,7 @@ stages:
   - build
   - test
   - review
+  - dast
   - staging
   - canary
   - production
@@ -130,6 +131,23 @@ sast:container:
   artifacts:
     paths: [gl-sast-container-report.json]
 
+dast:
+  stage: dast
+  allow_failure: true
+  image: owasp/zap2docker-stable
+  variables:
+    POSTGRES_DB: "false"
+  script:
+    - dast
+  artifacts:
+    paths: [gl-dast-report.json]
+  only:
+    refs:
+      - branches
+    kubernetes: active
+  except:
+    - master
+
 review:
   stage: review
   script:
@@ -270,8 +288,8 @@ production:
     docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.1
     apk add -U wget ca-certificates
     docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG}
-    wget https://github.com/arminc/clair-scanner/releases/download/v6/clair-scanner_linux_386
-    mv clair-scanner_linux_386 clair-scanner
+    wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
+    mv clair-scanner_linux_amd64 clair-scanner
     chmod +x clair-scanner
     touch clair-whitelist.yml
     ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-sast-container-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true
@@ -327,6 +345,12 @@ production:
       replicas="$new_replicas"
     fi
 
+    if [[ "$CI_PROJECT_VISIBILITY" != "public" ]]; then
+      secret_name='gitlab-registry'
+    else
+      secret_name=''
+    fi
+
     helm upgrade --install \
       --wait \
       --set service.enabled="$service_enabled" \
@@ -334,6 +358,7 @@ production:
       --set image.repository="$CI_APPLICATION_REPOSITORY" \
       --set image.tag="$CI_APPLICATION_TAG" \
       --set image.pullPolicy=IfNotPresent \
+      --set image.secrets[0].name="$secret_name" \
       --set application.track="$track" \
       --set application.database_url="$DATABASE_URL" \
       --set service.url="$CI_ENVIRONMENT_URL" \
@@ -462,6 +487,11 @@ production:
   }
 
   function create_secret() {
+    echo "Create secret..."
+    if [[ "$CI_PROJECT_VISIBILITY" == "public" ]]; then
+      return
+    fi
+
     kubectl create secret -n "$KUBE_NAMESPACE" \
       docker-registry gitlab-registry \
       --docker-server="$CI_REGISTRY" \
@@ -471,6 +501,14 @@ production:
       -o yaml --dry-run | kubectl replace -n "$KUBE_NAMESPACE" --force -f -
   }
 
+  function dast() {
+    export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
+
+    mkdir /zap/wrk/
+    /zap/zap-baseline.py -J gl-dast-report.json -t "$CI_ENVIRONMENT_URL" || true
+    cp /zap/wrk/gl-dast-report.json .
+  }
+
   function performance() {
     export CI_ENVIRONMENT_URL=$(cat environment_url.txt)