-
-
Save hyperupcall/7edd9f31843d40b12c1db2ff40a283d9 to your computer and use it in GitHub Desktop.
#!/bin/sh -eu | |
# code licensed under BSD 2-Clause "Simplified" License | |
# see `change-master-branch-to-main.sh --help` for usage | |
# see twitter thread for more details: https://twitter.com/EdwinKofler/status/1272729160620752898 | |
site="github.com" | |
oldDefaultBranch="master" | |
newDefaultBranch="main" | |
bin="gh" # or set to 'hub' | |
user="${1:-""}" | |
repo="${2:-""}" | |
# ------------------- helper functions ------------------- # | |
showHelp() { | |
echo "change-master-branch-to-main.sh" | |
echo | |
echo "Description:" | |
echo " Cross-platform shell script to change the 'master' branch to" | |
echo " 'main' for the local and remote repository. Should work with" | |
echo " providers besides Github, but I haven't tested that" | |
echo | |
echo "Usage:" | |
echo " change-master-branch-to-main.sh [username] [repo name]" | |
echo " Rename the 'master' branch to 'main' both for the local" | |
echo " and remote repository with the specified variables. It" | |
echo " also sets the default branch to 'main' if the previous" | |
echo " default was 'master'" | |
echo " change-master-branch-to-main.sh" | |
echo " Same as above, but intelligently guesses (and ask user for" | |
echo " confirmation) the github user and repo names" | |
echo | |
echo "Requirements:" | |
echo " 'jq' and 'gh' are optional dependencies and are only required" | |
echo " when trying to update the GitHub default branch" | |
echo | |
echo "Examples:" | |
echo " change-master-branch-to-main.sh eankeen deno-babel" | |
} | |
# get the GitHub username, if it wasn't already specified | |
askUser() { | |
# return if user is already set (passed as arg) | |
test ! -z "$user" && return | |
# get github username and strip quotes | |
url="$(git config --get remote.origin.url)" | |
# if url looks like [email protected]:user/repo | |
if [ "$(echo "$url" | cut -d'@' -f1)" = "git" ]; then | |
user="$(echo "$url" | sed -E "s/(.*:)(.*)(\/.*)/\2/g")" | |
else | |
user="$(echo "$url" | sed -E "s/(.*$site\/)(.*)(\/.*)/\2/g")" | |
fi | |
printInfo "github username (default: %s): " "$user" | |
read -r | |
# trim whitespace | |
REPLY="$(echo "$REPLY" | xargs)" | |
user="${REPLY:-$user}" | |
printInfo "input: $user\n\n" | |
} | |
# get the GitHub repository name, if it wasn't already specified | |
askRepo() { | |
# return if repo is already set (passed as arg) | |
test ! -z "$repo" && return | |
url="$(git config --get remote.origin.url)" | |
repo="$(basename -s .git "$url")" | |
printInfo "github repository name (default: %s): " "$repo" | |
read -r | |
# trim whitespace | |
REPLY="$(echo "$REPLY" | xargs)" | |
repo="${REPLY:-$repo}" | |
printInfo "input: $repo\n\n" | |
} | |
remoteMainExists() { | |
git show-branch "refs/remotes/origin/$newDefaultBranch" >/dev/null 2>&1 | |
} | |
remoteMasterExists() { | |
git show-branch "refs/remotes/origin/$oldDefaultBranch" >/dev/null 2>&1 | |
} | |
localMainExists() { | |
git rev-parse --verify --quiet "refs/heads/$newDefaultBranch" >/dev/null | |
} | |
localMasterExists() { | |
git rev-parse --verify --quiet "refs/heads/$oldDefaultBranch" >/dev/null | |
} | |
hasColor() { | |
test -t 1 && command -v tput >/dev/null && \ | |
test -n "$(tput colors)" && test "$(tput colors)" -ge 8 | |
} | |
hasBinAndJq() { | |
command -v jq >/dev/null && command -v "$bin" >/dev/null | |
} | |
printInfo() { | |
if hasColor; then | |
printf "\033[0;94m" | |
# shellcheck disable=SC2059 | |
printf "$@" | |
printf "\033[0m" | |
else | |
# shellcheck disable=SC2059 | |
printf "$@" | |
fi | |
} | |
# ------------------------- main ------------------------- # | |
test "${1:-""}" = "--help" && showHelp && exit | |
git fetch --all | |
git checkout "$oldDefaultBranch" | |
git push origin "$oldDefaultBranch" | |
# ensure 'main' is the default locally | |
if ! localMainExists; then | |
printInfo "renaming '$oldDefaultBranch' to '$newDefaultBranch' locally\n" | |
git checkout $oldDefaultBranch | |
git branch --move $oldDefaultBranch "$newDefaultBranch" | |
fi | |
# ensure 'main' is at remote | |
if ! remoteMainExists; then | |
printInfo "setting '$newDefaultBranch' as default upstream branch\n" | |
git checkout "$newDefaultBranch" | |
git push --set-upstream origin "$newDefaultBranch" | |
fi | |
# remove local 'master' branch | |
if localMasterExists; then | |
printInfo "renaming local $oldDefaultBranch branch\n" | |
git branch --delete $oldDefaultBranch | |
fi | |
# ensure github default branch is 'main' | |
if hasBinAndJq; then | |
askRepo | |
askUser | |
beforeNewbranch="$("$bin" api "repos/$user/$repo" -X GET | jq --raw-output ".default_branch")" | |
# sets new default branch | |
if test "$beforeNewbranch" = "$oldDefaultBranch"; then | |
"$bin" api "repos/$user/$repo" -X PATCH -F default_branch="$newDefaultBranch" | |
fi | |
afterNewbranch="$("$bin" api "repos/$user/$repo" -X GET | jq --raw-output ".default_branch")" | |
printInfo "default branch at $user/$repo was: '$beforeNewbranch'\n" | |
printInfo "default branch at $user/$repo is now: '$afterNewbranch'\n" | |
fi | |
# remove remote 'master' branch | |
if remoteMasterExists; then | |
printInfo "deleting remote $oldDefaultBranch branch\n" | |
# if this fails, it may be due to forgetting | |
# to reset the default branch to 'main' on github | |
git push origin --delete $oldDefaultBranch | |
test ! $? && printInfo "this probably errored since '$oldDefaultBranch' is still the 'default branch' on github" \ | |
&& printInfo "if you install \`gh\` and \`jq\` this will be done for you" | |
fi |
@hkatzdev yah! since your comment i added a variable at the top for that ;)
I don't know why but I kept getting ! [remote rejected] master (refusing to delete the current branch: refs/heads/master) error: failed to push some refs to 'https://github.com/hkatzdev/hackagotchi.git'
when running the script. Every time I tried to clone with hub it wouldn't change the head ref, even though I ended up manually doing it in github. Maybe its a hub problem?
@hkatzdev can you please provide more output? like it should say default branch at hkatzdev/hackagotchi is now 'main'
somewhere
i would recommend troubleshooting with hub api "repos/hkatzdev/hackagotchi" -X GET | jq
and hub api "repos/hkatzdev/hackagotchi" -X PATCH -F default_branch="main"
. does that latter output anything? if not maybe there are some issues with authentication? you can also remove the >/dev/null
from line 162 for more details
@eankeen it so cool. will this same script work for GITLAB as well ?
@eankeen it so cool. will this same script work for GITLAB as well ?
Thank you! It should work, provided you set I don't think GitLab is fully supported. To get complete support, you'll have to modify the requests starting near line 150 that use the site=gitlab.com
near the top - but it's not tested :)gh
or hub
utility (basically anything that executes the utility referred to by "$bin")
This is really cool - would it be possible to add an option to change main to any name, in case people want trunk for instance?