max pleaner
max pleaner

Reputation: 26768

Alias git branches to replace "master" with "main"

I work on a bunch of different repos - many of them use master, and many of them use main.

I also have various shell aliases set up for git commands, e.g. gcm for git checkout master.

The problem is that I cannot use these aliases on repos where master doesn't exist. It's obviously not a big deal, because I just need to type out the command manually in that case, but it's slightly annoying.

I am wondering if there's a way I can "alias" branches in git, so when I say git push origin master it can just automatically replace that with main.

Upvotes: 0

Views: 981

Answers (3)

torek
torek

Reputation: 488183

I personally like j6t's answer, but note that when you run git clone, the default branch in the origin repository, after mapping to remote-tracking name, becomes the origin/HEAD symbolic-reference name. So you could use git rev-parse --symbolic-full-name refs/remotes/origin/HEAD to discover whether this is refs/remotes/origin/master, refs/remotes/origin/main, or some other value.

Using that result, you can then choose whether to use the name main or master or some other value.

For repositories where the origin's default branch is, e.g., develop, this means you might resolve to develop. If that's what you want, that's good.

You can combine these ideas: after git clone (perhaps instead of git clone), run a script that reads:

#! /bin/sh
rhead=$(git rev-parse --symbolic-full-name origin/HEAD) || {
    echo "can't figure out default, not creating symbolic name"
    exit 1
}
rhead=${rhead#refs/remotes/origin/}
case "$rhead" in
master) ;; # do nothing
*)
    git symbolic-ref refs/heads/master "refs/heads/$rhead"
    echo "master -> $rhead"
    ;;
esac
exit 0

(note: the above is entirely untested).

Upvotes: 0

j6t
j6t

Reputation: 13387

In a repository that has main, but not master, the simplest is to create a branch alias master that points to main:

git symbolic-ref refs/heads/master refs/heads/main

This gives the following list of branches (for example):

$ git branch -a
* main
  master -> main
  side

Now everytime your commands reference master they apply to main. Even when you push master, the actual target is main:

$ git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 241 bytes | 241.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To ../gitupstream
   f57e131..15c1aad  master -> main

Upvotes: 3

larsks
larsks

Reputation: 311606

You could use git show-ref -q to check if the branch exists:

alias gcm='git show-ref -q --heads main && git checkout main || git checkout master'

You could write a shell function to return the default branch name:

default_branch_name() {
    git show-ref -q --heads main && echo main || echo master
}

alias gcm="git checkout $(default_branch_name)"

That probably simplifies writing additional aliases.


The above assumes only two possible names for the primary branch. You could of course check for more:

default_branch_name() {
    for name in master trunk main; do
        git show-ref -q --heads $name && break
    done

    echo $name
}

Upvotes: 2

Related Questions