TechEarl

Git Branch Basics: Current, Default, Previous, and Deleting Branches

The git branch commands I reach for daily: print the current branch, find a remote's default branch, jump to the previous branch, rename, and delete a branch locally and on the remote. Modern git switch syntax throughout.

Ishan Karunaratne⏱️ 8 min readUpdated
Share thisCopied
Print the current git branch, find a remote's default branch, switch to the previous branch, rename a branch, and delete a branch locally and on the remote with modern git switch syntax.

These are the git branch commands I actually type in a day, with no extra words: print the branch I am on, find a remote's default branch, jump back to the one I was just on, rename the current branch, and delete a branch both locally and on the remote.

bash
git branch --show-current                          # which branch am I on?
git switch other-branch                            # move to an existing branch
git switch -c new-branch                           # create and move to a new one
git switch -                                        # back to the previous branch
git branch -m better-name                           # rename the current branch
git branch -d feature                               # delete a merged local branch
git push origin --delete feature                    # delete the remote branch

The rest of this page is the detail behind each of those: the older forms still worth knowing, why git switch replaced git checkout for this work, and the gotchas that bite when you delete or rename.

A note on switch vs checkout up front, because it runs through everything below. git checkout does two unrelated jobs (moving between branches and restoring files), which is why it confuses people. Git 2.23 (August 2019) split those jobs into two focused commands: git switch for branches and git restore for files. Both are out of "experimental" and are what I reach for now. Every git checkout branch command still works, so nothing here breaks an old habit. I just lead with the clearer command.

Which branch am I on?

bash
git branch --show-current

This prints just the current branch name and nothing else, which is what you want in a script or a prompt. It landed in git 2.22 (June 2019), so on any reasonably current git it is the clean answer.

On an older git that predates --show-current, the portable fallback is:

bash
git rev-parse --abbrev-ref HEAD

That returns the branch name too, but with one quirk: in detached HEAD state (you checked out a tag or a raw commit, not a branch) it prints HEAD rather than a branch name, whereas git branch --show-current prints an empty line. Either is a fine signal that you are not on a branch; just know which you are testing for.

Plain git branch (no flags) lists your local branches and marks the current one with an asterisk, which is the human-eyeball version of the same question.

Switch branches, and create one in passing

bash
git switch main                 # move to an existing branch
git switch -c new-feature       # create new-feature and move to it

git switch -c new-feature is the modern replacement for git checkout -b new-feature: create a branch off your current HEAD and switch to it in one step. Use -C (capital) to reset the branch if it already exists, the same way checkout -B did.

To branch off a specific starting point rather than wherever you are now, name it:

bash
git switch -c hotfix main       # new branch hotfix, started from main

Jump back to the previous branch

bash
git switch -

The bare - means "the branch I was on before this one," exactly like cd - jumps to your previous directory. It is the fastest way to bounce between a feature branch and main without typing either name. The older form git checkout - does the same thing and is fine on any git.

Find a remote's default branch

The default branch is the one a fresh clone checks out: historically master, now usually main on new repositories. When you script against "whatever the default is," do not hardcode the name. Ask git.

The offline answer, no network call, reads the symbolic ref your clone already stores:

bash
git symbolic-ref refs/remotes/origin/HEAD --short

That prints something like origin/main. Strip the origin/ prefix if you only want the branch name:

bash
git symbolic-ref refs/remotes/origin/HEAD --short | sed 's@^origin/@@'

One caveat: that local ref is set at clone time and is not automatically updated if the remote later changes its default. If it is missing or stale, re-point it from the remote:

bash
git remote set-head origin --auto

If you would rather ask the remote directly (a network round trip, but always current), git remote show origin reports it in a HEAD branch: line:

bash
git remote show origin
# look for:  HEAD branch: main

To pull just that value out for a script:

bash
git remote show origin | sed -n '/HEAD branch/s/.*: //p'

I reach for the symbolic-ref form by default (it is instant and offline) and fall back to remote show origin only when I suspect the local ref is wrong.

Rename a branch

bash
git branch -m better-name              # rename the branch you are on
git branch -m old-name better-name     # rename a branch you are not on

-m moves (renames) a branch. Renaming a branch that has already been pushed is the part people forget: the rename is purely local, so you then push the new name and delete the old one on the remote.

bash
git push origin -u better-name         # push the renamed branch, set upstream
git push origin --delete old-name      # remove the old name from the remote

Delete a local branch

bash
git branch -d feature        # safe delete: refuses if not merged
git branch -D feature        # force delete: removes it regardless

-d is the safe form. It refuses to delete a branch that holds commits not yet merged into its upstream or the current branch, which is git stopping you from throwing work away by accident. When you are sure (you abandoned an experiment, say), -D forces it through. -D is shorthand for --delete --force.

You cannot delete the branch you are standing on. Switch off it first (git switch main), then delete.

Delete a remote branch

bash
git push origin --delete feature

That deletes the branch named feature on the remote called origin. Deleting a remote branch and deleting your local copy are two separate acts: this command does nothing to your local feature branch, and git branch -d feature does nothing to the remote. To fully retire a branch you run both.

You will also see the older colon syntax, which still works:

bash
git push origin :feature

Read it as "push nothing into the remote ref feature," and pushing nothing into a ref deletes it. The --delete form does the same thing and says what it means, so I prefer it.

Deleting the remote branch does not clean up the stale remote-tracking ref (origin/feature) in other clones. Prune those with:

bash
git fetch --prune

List branches, with detail

bash
git branch                # local branches, * marks current
git branch -a             # local + remote-tracking branches
git branch -r             # remote-tracking branches only
git branch -vv            # each branch + last commit + its upstream and ahead/behind

git branch -vv is the one I lean on most when a branch's push is misbehaving: it shows each local branch's tracked upstream and whether you are ahead or behind, which is usually where the confusion is. If a branch is tracking the wrong upstream (or none), fix it in place without re-pushing:

bash
git branch -u origin/main              # set the current branch's upstream
git branch -u origin/main feature      # set it for a branch you are not on

-u is short for --set-upstream-to. This is the per-branch fix; git push -u origin feature does the same thing for a branch the first time you push it.

When it is time to clean up, these two filters tell you which branches are safe to delete and which still hold unmerged work:

bash
git branch --merged       # branches already merged into HEAD: safe to delete
git branch --no-merged    # branches with commits not yet in HEAD: don't -d these

--merged lists the branches reachable from your current HEAD (so git branch -d will accept them without complaint); --no-merged lists the ones that still carry work, which are exactly the branches -d refuses and -D would silently throw away. Pass a commit to either to test against something other than HEAD, for example git branch --merged main.

When you make a branching mistake (deleted too much, switched and lost track of work), the recovery path is git reflog and friends. See how to undo things in git for that whole toolkit.

FAQ

See also

Sources

Authoritative references this article was fact-checked against.

Tagsgitgit branchgit switchcurrent branchdefault branchdelete remote branchversion controlCLI

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

Git Tags: Create, Push, List, and Delete

Create, push, list, and delete git tags from the command line. When to use an annotated tag over a lightweight one, why git push leaves your tags behind, and how to delete a tag on the remote.

Git Branching Explained for Beginners

What a Git branch actually is, how HEAD points at your current spot, and the commands to create, switch, list, rename, and delete branches with confidence.