0

Say a daring developer wishes to undertake the simple (and recommended) task of renaming their repositories master branch to main. Should be simple right?

Such a developer thus grabs the latest changes from master, renames the branch, fetches the upstream and moves the origin. Something along the lines of this:

git pull origin master
git branch -m master main
git fetch origin
git branch -u origin/main main

Swell.

Now, however, the piece of advice that every website recommends is to escape the comfort of your terminal and venture to your web browser and, (dare I say it) click to change the default branch.

Easy some might say, however, in the cases of organizations with multiple repositories, this doesn't scale well. Assuming that all of the recommended checks are in place and every repository is ready to be renamed:

How then might the remote master branch be deleted such that you could pack the whole process in a short script and automate it all without having to go to the web browser?

Such a developer might naively think to try to delete the remote master branch like any other remote branch with:

git push origin --delete master

But the master branch (or whatever the default branch was named as) is not like other branches. It's protected, and thus this will result in error: failed to push some refs to 'https://github.com/username/repo-name.git'. Moreover, we just renamed master

Constraints: Web API is fair game, Github CLI / API is fair game, basically anything that could run on a headless server without access to a web GUI, and all history should be maintained (Thanks!)

K. W. Cooper
  • 313
  • 3
  • 12
  • Does this answer your question? [How do I delete a Git branch locally and remotely?](https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely) – hobbs Jan 23 '23 at 23:55
  • No, from my understanding, that advice applies to every other remote branch other than master. – K. W. Cooper Jan 24 '23 at 00:00
  • 1
    So you claim that some one particular branch name has a kind of magic aura about it? – matt Jan 24 '23 at 00:19
  • @matt Of course not. I claim that the default branch is protected and needs to be changed via the web GUI. 99% of the time, this is "master" (or since recently, "main"). – K. W. Cooper Jan 24 '23 at 00:22
  • You can't delete the remote master branch because it is still the default HEAD on the remote repo. See https://stackoverflow.com/questions/847609/change-the-branch-name-on-github-that-references-head. If your remote repos are on machines you can log into, you can change the HEAD there directly (and then delete master) – Chris Dodd Jan 24 '23 at 00:34
  • 1
    https://docs.github.com/en/rest/branches/branch-protection?apiVersion=2022-11-28#update-branch-protection – phd Jan 24 '23 at 00:36
  • Does this answer your question? [Change the branch name on github that references HEAD](https://stackoverflow.com/questions/847609/change-the-branch-name-on-github-that-references-head) – Chris Dodd Jan 24 '23 at 00:38
  • @ChrisDodd alas `git remote set-head origin main` and then `git push origin --delete master` hasn't done the trick either – K. W. Cooper Jan 24 '23 at 00:46
  • 1
    @phd was close: the api call that works is: `gh api --method POST -H "Accept: application/vnd.github.v3+json" "/repos/username/repo-name/branches/master/rename" -f new_name='main'` – K. W. Cooper Jan 24 '23 at 00:56

2 Answers2

2

Branch protection is not a git feature or concept in any way. Protection is a concept/feature over the top of git, implemented by GitHub, GitLab, and so on.

If you want it to be automated you will also need to call GitHub’s API at the right point (beginning) of the process.

See this SO thread for more discussion about that topic.

Credit to @phd in the comments for the GitHub API. You can use curl to call it in your script.

Kit
  • 20,354
  • 4
  • 60
  • 103
2

As was pointed out, Github protected branches cannot be edited via pure git. Luckily, the new Github CLI worked for me, through its API submodule gh api

Rename the remote Github default branch from the default to your new name:

gh api --method POST -H "Accept: application/vnd.github.v3+json" "/repos/<USERNAME>/<REPOSITORY-NAME>/branches/master/rename" -f new_name='main'

Then tidy up the changes locally (commands as recommended by Github):
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a

Thanks @Kit and @phd for helping me converge on this!

K. W. Cooper
  • 313
  • 3
  • 12