./ahmedhashim

One-liners: git sync

According to my shell history, git sync is my most-used Git command.

I jump between repos all day, so I use one command that checks out the branch behind origin/HEAD, pulls with rebase, and deletes local branches whose upstream is gone.

Here’s what it looks like in my ~/.gitconfig:

[fetch]
  prune = true
[pull]
  rebase = true
[alias]
  db = !git symbolic-ref refs/remotes/origin/HEAD --short | sed 's@origin/@@'
  sync = !git checkout $(git db) && git pull && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

Breaking it down

First, prune on every fetch:

[fetch]
  prune = true

This deletes stale remote-tracking refs. Without it, origin/* drifts from reality.

Then make pull rebase by default:

[pull]
  rebase = true

This makes git pull “fetch + rebase” instead of “fetch + merge”, keeping history linear and avoiding pull-merge noise.

Next, resolve the default branch dynamically:

[alias]
  db = !git symbolic-ref refs/remotes/origin/HEAD --short | sed 's@origin/@@'

origin/HEAD follows the remote default branch (main, master, etc.). Strip origin/, and you get a checkout-ready branch name. Hardcoding main is brittle.

Finally, the sync one-liner:

[alias]
  sync = !git checkout $(git db) && git pull && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

The leading ! makes this a shell alias, so pipes and command substitution work.

  • git checkout $(git db): move to the repo’s actual default branch.
  • git pull: fetch and rebase local commits (if any) onto the updated default branch.
  • git branch -vv | grep ': gone]': find branches whose upstream was deleted.
  • awk '{print $1}' | xargs -r git branch -D: extract and delete them.

-D is intentional: squash merges create a new commit on the default branch, so -d often refuses to delete the source branch. If upstream is gone, I treat the branch as disposable. Use -d only if you keep long-lived local branches.