diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 89e82e5db97495e077d669c9463494feadd6f76d..8d528e123e180dfa65e4dd0f87b936af5ded2041 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -132,13 +132,23 @@ def projects def update if Groups::UpdateService.new(@group, current_user, group_params).execute - redirect_to edit_group_path(@group, anchor: params[:update_section]), notice: "Group '#{@group.name}' was successfully updated." + notice = "Group '#{@group.name}' was successfully updated." + + redirect_to edit_group_origin_location, notice: notice else @group.reset render action: "edit" end end + def edit_group_origin_location + if params.dig(:group, :redirect_target) == 'repository_settings' + group_settings_repository_path(@group, anchor: 'js-default-branch-name') + else + edit_group_path(@group, anchor: params[:update_section]) + end + end + def destroy Groups::DestroyService.new(@group, current_user).async_execute diff --git a/app/models/group.rb b/app/models/group.rb index 32ccc4ed3a7e5f323986c00bd4f785193249dc5b..a20888e040b82f0520ed05255fe4ae80e56ee9ca 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -109,6 +109,8 @@ class Group < Namespace .where("project_authorizations.user_id IN (?)", user_ids) end + delegate :default_branch_name, to: :namespace_settings + class << self def sort_by_attribute(method) if method == 'storage_size_desc' diff --git a/app/models/namespace_setting.rb b/app/models/namespace_setting.rb index 6f31208f28b3d4bb101d54b118585e3c3442ef31..50844403d7f5149b41465fadafcf02502cd28766 100644 --- a/app/models/namespace_setting.rb +++ b/app/models/namespace_setting.rb @@ -6,10 +6,18 @@ class NamespaceSetting < ApplicationRecord validate :default_branch_name_content validate :allow_mfa_for_group + before_validation :normalize_default_branch_name + NAMESPACE_SETTINGS_PARAMS = [:default_branch_name].freeze self.primary_key = :namespace_id + private + + def normalize_default_branch_name + self.default_branch_name = nil if default_branch_name.blank? + end + def default_branch_name_content return if default_branch_name.nil? diff --git a/app/views/groups/settings/repository/_initial_branch_name.html.haml b/app/views/groups/settings/repository/_initial_branch_name.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..3ef8dccae0834a86202c6a770fddf426ebf9c744 --- /dev/null +++ b/app/views/groups/settings/repository/_initial_branch_name.html.haml @@ -0,0 +1,22 @@ +%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) } + .settings-header + %h4 + = _('Default initial branch name') + %button.gl-button.js-settings-toggle{ type: 'button' } + = expanded_by_default? ? _('Collapse') : _('Expand') + %p + = _('Set the default name of the initial branch when creating new repositories through the user interface.') + .settings-content + = form_for @group, url: group_path(@group, anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f| + = form_errors(@group) + - fallback_branch_name = 'master' + + %fieldset + .form-group + = f.label :default_branch_name, _('Default initial branch name'), class: 'label-light' + = f.text_field :default_branch_name, value: group.namespace_settings&.default_branch_name, placeholder: 'master', class: 'form-control' + %span.form-text.text-muted + = (_("Changes affect new repositories only. If not specified, either the configured application-wide default or Git's default name %{branch_name_default} will be used.") % { branch_name_default: fallback_branch_name }).html_safe + + = f.hidden_field :redirect_target, value: "repository_settings" + = f.submit _('Save changes'), class: 'gl-button btn-success' diff --git a/app/views/groups/settings/repository/show.html.haml b/app/views/groups/settings/repository/show.html.haml index ff0c9de4fef866365bd8288b244ccae0ef480398..a581932040558753ec22347d64b6ae8b34de4595 100644 --- a/app/views/groups/settings/repository/show.html.haml +++ b/app/views/groups/settings/repository/show.html.haml @@ -4,3 +4,4 @@ - deploy_token_description = s_('DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group.') = render "shared/deploy_tokens/index", group_or_project: @group, description: deploy_token_description += render "initial_branch_name", group: @group diff --git a/changelogs/unreleased/feature-group-default-initial-branch-name.yml b/changelogs/unreleased/feature-group-default-initial-branch-name.yml new file mode 100644 index 0000000000000000000000000000000000000000..b3059a2c0b2d6ee52ce18d9584c493d0207839bd --- /dev/null +++ b/changelogs/unreleased/feature-group-default-initial-branch-name.yml @@ -0,0 +1,5 @@ +--- +title: Add Default Initial Branch Name for Repositories Group Setting +merge_request: 43290 +author: +type: added diff --git a/doc/user/group/index.md b/doc/user/group/index.md index 7a816c96f599d5e9b9fc21394db2d1e7e3035854..59b24ea8847e03db9e1df81667b5346c0ef93f59 100644 --- a/doc/user/group/index.md +++ b/doc/user/group/index.md @@ -518,6 +518,23 @@ If you want to retain ownership over the original namespace and protect the URL redirects, then instead of changing a group's path or renaming a username, you can create a new group and transfer projects to it. +### Group repository settings + +You can change settings that are specific to repositories in your group. + +#### Custom initial branch name **(CORE ONLY)** + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/43290) in GitLab 13.6. + +By default, when you create a new project in GitLab, the initial branch is called `master`. +For groups, a group administrator can customize the initial branch name to something +else. This way, every new project created under that group from then on will start from the custom branch name rather than `master`. To do so: + +1. Go to the **Group page > Settings > Repository** and expand **Default initial + branch name**. +1. Change the default initial branch to a custom name of your choice. +1. **Save Changes**. + ### Remove a group To remove a group and its contents: diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d04a3507c37e1ec8c9f696c0a9f3073d4c2d88b5..06b84ce3f323ab0db8eeee97674926e39d5dec39 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4923,6 +4923,9 @@ msgstr "" msgid "Changes affect new repositories only. If not specified, Git's default name %{branch_name_default} will be used." msgstr "" +msgid "Changes affect new repositories only. If not specified, either the configured application-wide default or Git's default name %{branch_name_default} will be used." +msgstr "" + msgid "Changes are shown as if the %{b_open}source%{b_close} revision was being merged into the %{b_open}target%{b_close} revision." msgstr "" diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb index d20303027e592b5d69ffefd68a0ddd03d4c8fab0..3c1609a260531d37f933df0d831f242a7b8f2c3f 100644 --- a/spec/features/groups/settings/repository_spec.rb +++ b/spec/features/groups/settings/repository_spec.rb @@ -25,4 +25,21 @@ let(:entity_type) { 'group' } end end + + context 'Default initial branch name' do + before do + visit group_settings_repository_path(group) + end + + it 'has the setting section' do + expect(page).to have_css("#js-default-branch-name") + end + + it 'renders the correct setting section content' do + within("#js-default-branch-name") do + expect(page).to have_content("Default initial branch name") + expect(page).to have_content("Set the default name of the initial branch when creating new repositories through the user interface.") + end + end + end end diff --git a/spec/models/namespace_setting_spec.rb b/spec/models/namespace_setting_spec.rb index c6e8d5b129cbacb5c55ef188288eaf5fc74e7182..59b7510051f65d4622349936ae657981f9f91a2f 100644 --- a/spec/models/namespace_setting_spec.rb +++ b/spec/models/namespace_setting_spec.rb @@ -36,13 +36,10 @@ context "when an empty string" do before do - namespace_settings.default_branch_name = '' + namespace_settings.default_branch_name = "" end - it "returns an error" do - expect(namespace_settings.valid?).to be_falsey - expect(namespace_settings.errors.full_messages).not_to be_empty - end + it_behaves_like "doesn't return an error" end end