diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 98db0d8fa9bdc05c5cfeb578683f18bc3dac9de3..6aed65b586ecbed6ea959438a2495ed8e15f6132 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -2825,7 +2825,6 @@ Layout/LineLength:
     - 'ee/spec/services/ee/boards/issues/list_service_spec.rb'
     - 'ee/spec/services/ee/boards/lists/max_limits_spec.rb'
     - 'ee/spec/services/ee/ci/pipeline_processing/atomic_processing_service_spec.rb'
-    - 'ee/spec/services/ee/commits/create_service_spec.rb'
     - 'ee/spec/services/ee/git/wiki_push_service_spec.rb'
     - 'ee/spec/services/ee/groups/autocomplete_service_spec.rb'
     - 'ee/spec/services/ee/groups/deploy_tokens/create_service_spec.rb'
diff --git a/ee/app/services/ee/commits/create_service.rb b/ee/app/services/ee/commits/create_service.rb
index af5b9c35bf78277a63d8e42ed15da4251af2222b..fd4286ccee89bbf228cfd547bd6b800a381ab433 100644
--- a/ee/app/services/ee/commits/create_service.rb
+++ b/ee/app/services/ee/commits/create_service.rb
@@ -15,13 +15,21 @@ def validate!
       end
 
       def validate_repository_size!
-        size_checker = project.repository_size_checker
-
         if size_checker.above_size_limit?
           raise_error(size_checker.error_message.commit_error)
         end
       end
 
+      def size_checker
+        root_namespace = project.namespace.root_ancestor
+
+        if ::Namespaces::Storage::EnforcementCheckService.enforce_limit?(root_namespace)
+          ::EE::Namespace::RootStorageSize.new(root_namespace)
+        else
+          project.repository_size_checker
+        end
+      end
+
       def extracted_paths
         paths = []
 
diff --git a/ee/spec/features/ide/user_commits_changes_spec.rb b/ee/spec/features/ide/user_commits_changes_spec.rb
index 2673e6a347e422b0a3efaadf7ecba5bdef290570..451ca263bbbfd34dc649a85c8e1b7b6a7718be4a 100644
--- a/ee/spec/features/ide/user_commits_changes_spec.rb
+++ b/ee/spec/features/ide/user_commits_changes_spec.rb
@@ -4,31 +4,67 @@
 
 RSpec.describe 'EE IDE user commits changes', :js do
   include WebIdeSpecHelpers
+  include NamespaceStorageHelpers
 
-  let(:project) { create(:project, :custom_repo, files: { 'docs/CODEOWNERS' => "[Backend]\n*.rb @ruby-owner" }) }
-  let(:ruby_owner) { create(:user, username: 'ruby-owner') }
-  let(:user) { project.first_owner }
+  context 'code owners' do
+    let(:project) { create(:project, :custom_repo, files: { 'docs/CODEOWNERS' => "[Backend]\n*.rb @ruby-owner" }) }
+    let(:ruby_owner) { create(:user, username: 'ruby-owner') }
+    let(:user) { project.first_owner }
 
-  before do
-    stub_licensed_features(code_owners: true, code_owner_approval_required: true)
+    before do
+      stub_licensed_features(code_owners: true, code_owner_approval_required: true)
 
-    project.add_developer(ruby_owner)
+      project.add_developer(ruby_owner)
 
-    create(:protected_branch,
-      name: 'master',
-      code_owner_approval_required: true,
-      project: project)
+      create(:protected_branch,
+        name: 'master',
+        code_owner_approval_required: true,
+        project: project)
 
-    sign_in(user)
+      sign_in(user)
 
-    ide_visit(project)
+      ide_visit(project)
+    end
+
+    it 'does not show an error message' do
+      ide_create_new_file('test.rb', content: '# A ruby file')
+
+      ide_commit
+
+      expect(page).not_to have_content('CODEOWNERS rule violation')
+    end
   end
 
-  it 'does not show an error message' do
-    ide_create_new_file('test.rb', content: '# A ruby file')
+  context 'when namespace storage limits have been exceeded', :saas do
+    let(:user) { create(:user) }
+    let(:group) { create(:group) }
+    let(:project) { create(:project, :repository, group: group) }
+    let(:expected_message) do
+      "Your push to this repository has been rejected because " \
+      "the namespace storage limit of 10 MB has been reached. " \
+      "Reduce your namespace storage or purchase additional storage."
+    end
+
+    before do
+      create(:gitlab_subscription, :ultimate, namespace: group)
+      create(:namespace_root_storage_statistics, namespace: group)
+      group.add_owner(user)
+
+      enforce_namespace_storage_limit(group)
+      set_storage_size_limit(group, megabytes: 10)
+      set_used_storage(group, megabytes: 14)
+
+      sign_in(user)
+    end
+
+    it 'rejects the commit' do
+      ide_visit(project)
+
+      ide_create_new_file('test.txt', content: 'A new file')
 
-    ide_commit
+      ide_commit
 
-    expect(page).not_to have_content('CODEOWNERS rule violation')
+      expect(page).to have_content(expected_message)
+    end
   end
 end
diff --git a/ee/spec/requests/api/commits_spec.rb b/ee/spec/requests/api/commits_spec.rb
index f847db607e77c188e4f2523e556f245cc04d9bd1..1699db54a39d1f518c250dc8ec2add8b573451ee 100644
--- a/ee/spec/requests/api/commits_spec.rb
+++ b/ee/spec/requests/api/commits_spec.rb
@@ -3,6 +3,8 @@
 require "spec_helper"
 
 RSpec.describe API::Commits do
+  include NamespaceStorageHelpers
+
   let_it_be(:user) { create(:user) }
   let_it_be(:project) { create(:project, :repository, creator: user, path: "my.project") }
 
@@ -170,6 +172,29 @@
         it_behaves_like "handling the codeowners interaction"
       end
     end
+
+    context 'with an exceeded namespace storage limit', :saas do
+      let(:namespace) { project.namespace }
+
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: namespace)
+        create(:namespace_root_storage_statistics, namespace: namespace)
+        enforce_namespace_storage_limit(namespace)
+        set_storage_size_limit(namespace, megabytes: 5)
+        set_used_storage(namespace, megabytes: 6)
+      end
+
+      it "rejects the request" do
+        post api(route, user), params: { branch: branch }
+
+        expect(response).to have_gitlab_http_status(:bad_request)
+        expect(json_response['message']).to eq(
+          'Your push to this repository has been rejected because the ' \
+          'namespace storage limit of 5 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+    end
   end
 
   describe "POST :id/repository/commits/:sha/revert" do
@@ -204,5 +229,28 @@
         it_behaves_like "handling the codeowners interaction"
       end
     end
+
+    context 'with an exceeded namespace storage limit', :saas do
+      let(:namespace) { project.namespace }
+
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: namespace)
+        create(:namespace_root_storage_statistics, namespace: namespace)
+        enforce_namespace_storage_limit(namespace)
+        set_storage_size_limit(namespace, megabytes: 5)
+        set_used_storage(namespace, megabytes: 6)
+      end
+
+      it "rejects the request" do
+        post api(route, user), params: { branch: branch }
+
+        expect(response).to have_gitlab_http_status(:bad_request)
+        expect(json_response['message']).to eq(
+          'Your push to this repository has been rejected because the ' \
+          'namespace storage limit of 5 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+    end
   end
 end
diff --git a/ee/spec/requests/api/files_spec.rb b/ee/spec/requests/api/files_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ab6de0f4e5b082a2e23a95cc910718dffe8ccdca
--- /dev/null
+++ b/ee/spec/requests/api/files_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Files do
+  include NamespaceStorageHelpers
+
+  let(:group) { create(:group) }
+  let(:user) { create(:user) }
+  let(:project) { create(:project, :repository, group: group) }
+  let(:file_path) { "files%2Fruby%2Fpopen%2Erb" }
+
+  before do
+    project.add_developer(user)
+  end
+
+  def route(file_path = nil)
+    "/projects/#{project.id}/repository/files/#{file_path}"
+  end
+
+  describe "POST /projects/:id/repository/files/:file_path" do
+    let(:file_path) { "new_subfolder%2Fnewfile%2Erb" }
+    let(:params) do
+      {
+        branch: "master",
+        content: "puts 8",
+        commit_message: "Added newfile"
+      }
+    end
+
+    context 'with an exceeded namespace storage limit', :saas do
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: group)
+        create(:namespace_root_storage_statistics, namespace: group)
+        enforce_namespace_storage_limit(group)
+        set_storage_size_limit(group, megabytes: 5)
+        set_used_storage(group, megabytes: 6)
+      end
+
+      it 'rejects the request' do
+        post api(route(file_path), user), params: params
+
+        expect(response).to have_gitlab_http_status(:bad_request)
+        expect(json_response['message']).to eq(
+          'Your push to this repository has been rejected because the ' \
+          'namespace storage limit of 5 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+    end
+  end
+
+  describe "PUT /projects/:id/repository/files/:file_path" do
+    let(:params) do
+      {
+        branch: 'master',
+        content: 'puts 8',
+        commit_message: 'Change file'
+      }
+    end
+
+    context 'with an exceeded namespace storage limit', :saas do
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: group)
+        create(:namespace_root_storage_statistics, namespace: group)
+        enforce_namespace_storage_limit(group)
+        set_storage_size_limit(group, megabytes: 5)
+        set_used_storage(group, megabytes: 6)
+      end
+
+      it 'rejects the request' do
+        put api(route(file_path), user), params: params
+
+        expect(response).to have_gitlab_http_status(:bad_request)
+        expect(json_response['message']).to eq(
+          'Your push to this repository has been rejected because the ' \
+          'namespace storage limit of 5 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+    end
+  end
+
+  describe "DELETE /projects/:id/repository/files/:file_path" do
+    let(:params) do
+      {
+        branch: 'master',
+        commit_message: 'Delete file'
+      }
+    end
+
+    context 'with an exceeded namespace storage limit', :saas do
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: group)
+        create(:namespace_root_storage_statistics, namespace: group)
+        enforce_namespace_storage_limit(group)
+        set_storage_size_limit(group, megabytes: 5)
+        set_used_storage(group, megabytes: 6)
+      end
+
+      it 'rejects the request' do
+        delete api(route(file_path), user), params: params
+
+        expect(response).to have_gitlab_http_status(:bad_request)
+        expect(json_response['message']).to eq(
+          'Your push to this repository has been rejected because the ' \
+          'namespace storage limit of 5 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+    end
+  end
+end
diff --git a/ee/spec/requests/api/submodules_spec.rb b/ee/spec/requests/api/submodules_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1cdf3c91028f76a9e7808ee3fbbbfb6b5fe6a5bb
--- /dev/null
+++ b/ee/spec/requests/api/submodules_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Submodules do
+  include NamespaceStorageHelpers
+
+  let(:user) { create(:user) }
+  let(:group) { create(:group) }
+  let(:project) { create(:project, :repository, group: group) }
+  let(:submodule) { 'six' }
+
+  let(:params) do
+    {
+      submodule: submodule,
+      commit_sha: 'e25eda1fece24ac7a03624ed1320f82396f35bd8',
+      branch: 'master',
+      commit_message: 'update submodule'
+    }
+  end
+
+  before do
+    project.add_developer(user)
+  end
+
+  def route(submodule)
+    "/projects/#{project.id}/repository/submodules/#{submodule}"
+  end
+
+  describe "PUT /projects/:id/repository/submodule/:submodule" do
+    context 'with an exceeded namespace storage limit', :saas do
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: group)
+        create(:namespace_root_storage_statistics, namespace: group)
+        enforce_namespace_storage_limit(group)
+        set_storage_size_limit(group, megabytes: 4)
+        set_used_storage(group, megabytes: 5)
+      end
+
+      it 'rejects the request' do
+        put api(route(submodule), user), params: params
+
+        expect(response).to have_gitlab_http_status(:bad_request)
+        expect(json_response['message']).to eq(
+          'Your push to this repository has been rejected because the ' \
+          'namespace storage limit of 4 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+    end
+  end
+end
diff --git a/ee/spec/services/ee/commits/create_service_spec.rb b/ee/spec/services/ee/commits/create_service_spec.rb
index 5240d958f14fbf660e3e7d8e1a2bf9168b5f2179..e3e79c2dcf92cb169572c431a07b0d546fc38c5a 100644
--- a/ee/spec/services/ee/commits/create_service_spec.rb
+++ b/ee/spec/services/ee/commits/create_service_spec.rb
@@ -3,33 +3,83 @@
 require 'spec_helper'
 
 RSpec.describe Commits::CreateService do
-  let(:project) { create(:project) }
+  include NamespaceStorageHelpers
+
   let(:user) { create(:user) }
-  let(:branch_name) { 'master' }
-  let(:extra_params) { {} }
+  let(:group) { create(:group) }
+  let(:project) { create(:project, group: group) }
 
   before do
     project.add_maintainer(user)
   end
 
   subject(:service) do
-    described_class.new(project, user, start_branch: branch_name, branch_name: branch_name, **extra_params)
+    described_class.new(project, user, start_branch: 'master', branch_name: 'master')
   end
 
   describe '#execute' do
-    before do
-      stub_licensed_features(repository_size_limit: true)
-      project.update!(repository_size_limit: 1)
-      allow(project.repository_size_checker).to receive(:current_size).and_return(2)
+    context 'when the repository size limit has been exceeded' do
+      before do
+        stub_licensed_features(repository_size_limit: true)
+        project.update!(repository_size_limit: 1)
+        allow(project.repository_size_checker).to receive(:current_size).and_return(2)
+      end
+
+      it 'raises an error' do
+        expect(Gitlab::ErrorTracking).to receive(:log_exception)
+          .with(instance_of(Commits::CreateService::ValidationError)).and_call_original
+
+        result = service.execute
+
+        expect(result[:status]).to be(:error)
+        expect(result[:message]).to eq(
+          'Your changes could not be committed, because this ' \
+          'repository has exceeded its size limit of 1 Byte by 1 Byte'
+        )
+      end
     end
 
-    subject(:result) { service.execute }
+    context 'when the namespace storage limit has been exceeded', :saas do
+      before do
+        create(:gitlab_subscription, :ultimate, namespace: group)
+        create(:namespace_root_storage_statistics, namespace: group)
+        enforce_namespace_storage_limit(group)
+        set_storage_size_limit(group, megabytes: 1)
+        set_used_storage(group, megabytes: 2)
+      end
+
+      it 'raises an error' do
+        expect(Gitlab::ErrorTracking).to receive(:log_exception)
+          .with(instance_of(Commits::CreateService::ValidationError)).and_call_original
+
+        result = service.execute
+
+        expect(result[:status]).to be(:error)
+        expect(result[:message]).to eq(
+          'Your push to this repository has been rejected because ' \
+          'the namespace storage limit of 1 MB has been reached. ' \
+          'Reduce your namespace storage or purchase additional storage.'
+        )
+      end
+
+      context 'with a subgroup project' do
+        let(:subgroup) { create(:group, parent: group) }
+        let(:project) { create(:project, group: subgroup) }
+
+        it 'raises an error' do
+          expect(Gitlab::ErrorTracking).to receive(:log_exception)
+            .with(instance_of(Commits::CreateService::ValidationError)).and_call_original
+
+          result = service.execute
 
-    it 'raises an error if the repositoy exceeds the size limit' do
-      expect(Gitlab::ErrorTracking).to receive(:log_exception)
-        .with(instance_of(Commits::CreateService::ValidationError)).and_call_original
-      expect(result[:status]).to be(:error)
-      expect(result[:message]).to eq('Your changes could not be committed, because this repository has exceeded its size limit of 1 Byte by 1 Byte')
+          expect(result[:status]).to be(:error)
+          expect(result[:message]).to eq(
+            'Your push to this repository has been rejected because ' \
+            'the namespace storage limit of 1 MB has been reached. ' \
+            'Reduce your namespace storage or purchase additional storage.'
+          )
+        end
+      end
     end
   end
 end