Skip to main content

Command Palette

Search for a command to run...

Git Notes: Branching & Merging

Published
5 min read
Git Notes: Branching & Merging
M

Mohamad's interest is in Programming (Mobile, Web, Database and Machine Learning). He is studying at the Center For Artificial Intelligence Technology (CAIT), Universiti Kebangsaan Malaysia (UKM).

Mental model

A branch is just a movable pointer to a commit. You create commits on a branch, then combine branches with merge or rebase. Keep your integration branch (main or develop) clean; do new work on short-lived feature branches.

o---o---o  (main)
         \
          o---o  (feature)

1) git branch — manage branches

Common tasks

git branch                 # list local branches; * marks current
git branch -vv             # with upstream & last commit
git branch -a              # local + remote-tracking
git branch feature/login   # create branch at current HEAD
git branch -d feature/x    # delete merged branch
git branch -D feature/x    # force delete (even if unmerged)
git branch --merged        # branches safe to delete
git branch --contains <commit>  # which branches include a commit

Rename / set upstream

git branch -m old-name new-name
git branch --set-upstream-to origin/feature/login

2) Switching branches — git switch (preferred) vs git checkout (legacy)

git switch (Git ≥ 2.23)

git switch main                    # switch existing
git switch -c feature/login        # create and switch (like checkout -b)
git switch -                       # jump back to previous branch

git checkout (older, still works)

git checkout main
git checkout -b feature/login

Note: git checkout also checks out files (not just branches). git switch is clearer for branch changes.

3) git merge — combine histories

  • Fast-forward (no merge commit when possible):

      git switch main
      git merge feature/login          # fast-forwards if main had no new commits
    
  • Three-way merge (creates a merge commit):

      # main and feature both advanced
      git switch main
      git merge feature/login          # may create a merge commit
    
  • Control behavior

      git merge --no-ff feature/x      # force a merge commit (preserve branch “bubble”)
      git merge --squash feature/x     # squash all feature commits into staged changes
      git merge --abort                # abort a conflicted merge
    

Resolve conflicts

# after conflicts appear:
git status                         # see conflicted files
# edit files, decide correct content
git add <fixed-files>
git merge --continue

4) git rebase — reapply commits on a new base

Use case: Keep a linear history by placing your work on top of updated main.

git switch feature/login
git fetch origin
git rebase origin/main             # move feature commits onto newest main
# fix conflicts -> edit -> git add -> git rebase --continue
# give up:
git rebase --abort

Interactive rebase (squash, reword, reorder):

git rebase -i HEAD~5               # edit last 5 commits

Safety rule: Don’t rebase shared branches that others already pulled. Rebasing rewrites history; use on personal feature branches before merging.

Pull with rebase (optional default)

git config pull.rebase true
git pull                           # now does fetch + rebase

5) git cherry-pick — copy specific commits

Apply one commit (or a range) onto current branch

git switch hotfix/urgent
git cherry-pick <commit-sha>       # apply a single commit
git cherry-pick A..B               # apply commits after A up to B (exclusive A, inclusive B)
git cherry-pick --no-commit <sha>  # stage changes without committing
git cherry-pick --abort            # cancel if conflicted

Tip: Use -x to record the source SHA in the message:

git cherry-pick -x <sha>

6) git stash — save work in progress

Quick save / restore

git stash push -m "WIP login UI"   # save modified/unstaged changes
git stash list                      # see stashes (stash@{0}, stash@{1}, …)
git stash show -p stash@{0}         # preview patch
git stash pop                       # apply latest and remove it from stash
git stash apply stash@{2}           # apply a specific stash (keep it)
git stash drop stash@{2}            # delete a specific stash

Keep untracked files too

git stash push -u -m "WIP incl untracked"

Resume into a new branch

git stash branch feature/wip stash@{0}

7) Merge vs Rebase — quick guidance

GoalPrefer
Preserve true merge history (feature “bubble”)merge (optionally --no-ff)
Keep linear history for readabilityrebase on latest main before merging
One clean commit for a noisy featuremerge --squash (then single commit) or rebase -i to squash
Bring just one fix across branchescherry-pick

Team rule of thumb

  • On personal feature branches: rebase freely to keep tidy.

  • On shared branches: avoid history rewrites; merge or revert instead.

8) Typical workflows

Feature development (linear)

git switch -c feature/auth
# commits …
git fetch origin
git rebase origin/main
git switch main
git merge --ff-only feature/auth   # or squash merge via PR
git branch -d feature/auth

Hotfix from main + backport

git switch -c hotfix/calc-bug main
# fix & commit
git push -u origin hotfix/calc-bug
# merge to main (and tag a release)
# backport to previous release branch:
git switch release/1.2
git cherry-pick <hotfix-commit-sha>

9) Remote tracking & cleanup

git push -u origin feature/payments   # set upstream
git branch -vv                        # see upstream for each branch
git push origin --delete feature/x    # remove remote branch
git fetch -p                          # prune deleted remote branches

10) Quick reference (copy/paste)

# Create & switch
git switch -c feature/x
git switch main        # (or: git checkout main)
git switch -           # toggle back

# Merge
git switch main
git merge feature/x
git merge --no-ff feature/x
git merge --squash feature/x
git merge --abort

# Rebase
git switch feature/x
git fetch origin
git rebase origin/main
git rebase -i HEAD~N
git rebase --continue
git rebase --abort

# Cherry-pick
git switch target-branch
git cherry-pick <sha>        # or A..B
git cherry-pick --abort

# Stash
git stash push -m "WIP"
git stash push -u -m "WIP incl untracked"
git stash list
git stash pop
git stash apply stash@{1}
git stash branch feature/wip stash@{0}

# Branch maintenance
git branch -a
git branch -vv
git branch --merged
git branch -d feature/x
git push origin --delete feature/x

.

2 views