Git - 重命名所有默认分支

Git - Rename All Default Branches

我使用 Gitlab 进行源代码管理。 Gitlab 最近切换到使用 main 作为新存储库的默认分支,如 here 所述,这很好,我已经调整了我的开发环境以匹配。

我也想更改我现有的存储库。 This tutorial 描述了一种方法来做到这一点,但涉及多个手动步骤并且一次只能在一个存储库上工作,更不用说复制历史记录的步骤了。由于我们的代码库由数百个存储库组成,这是不可行的。

有没有办法在 Gitlab 或 Gitbash 中自动执行此操作?

这只是从 master 创建一个名为 main 的新分支,删除 master 分支,并调整 default/protected 分支规则的问题。这些操作可以使用 GitLab API 执行,这将允许您编写这些操作的脚本。

基本步骤和API参考文献:

  1. 使用 create branch API 从 master

    创建 main 分支
  2. 使用edit project API设置默认分支为main

  3. 使用protect branch API保护main

  4. (可选)使用 unprotect branch API to remove protections from master and/or use the delete branch API 删除 master 分支。

当然,您必须有足够的权限才能在项目中执行所有这些操作。

最后,您还可以使用 list projects API 列出您的所有项目并遍历结果以将其应用到您的所有项目——您可以编写类似 for each project; do steps 1-4[= 的脚本23=]

使用 python-gitlab library,像这样的脚本应该可以正确执行所有这些步骤:

import gitlab

gl = gitlab.Gitlab("https://gitlab.example.com", private_token="your token")

# add your project IDs here
all_projects = [gl.projects.get(1234), gl.projects.get(4567), ...]

# or list all projects programatically: (careful if using gitlab.com!)
# all_projects = list(gl.projects.list(as_list=False))


def get_or_create_main_branch(project):
    try:
        b = project.branches.get("main")
        print("main branch already exists")
        return b
    except gitlab.exceptions.GitlabError:
        print("Creating main branch from ref:", project.default_branch)
        project.branches.create({"branch": "main", "ref": project.default_branch})
        print("Creating protection rule for main branch")
        # Edit access levels per your needs
        project.protectedbranches.create(
            {
                "name": "main",
                "merge_access_level": gitlab.const.DEVELOPER_ACCESS,
                "push_access_level": gitlab.const.MAINTAINER_ACCESS,
            }
        )
        return project.branches.get("main")


def fix_project(project):
    main_branch = get_or_create_main_branch(project)
    print("setting default branch to main...", end="")
    old_default_branch = project.branches.get(project.default_branch)
    project.default_branch = "main"
    project.save()
    print("Done!")
    print("deleting original default branch", old_default_branch.name, "...", end="")
    old_default_branch.delete()
    print("done!")


for project in all_projects:
    print("-" * 20)
    print("Checking", project.path_with_namespace, "for default branch")
    if project.default_branch != "main":
        print(
            f'Default branch is "{project.default_branch}", not "main". Attempting Fix...'
        )

        try:
            fix_project(project)
        except gitlab.exceptions.GitlabError as e:
            # sometimes bare repos without any commits will error out
            print("FATAL. Failure getting or creating main branch", e)
            print("Skipping")
            continue  # move on to next project in the loop
        print("successfully fixed", project.path_with_namespace)
    else:
        print('Default branch is already "main", skipping')
        continue