git Distributed version control system, created by Linus Torvalds

Branching & Merging

A branch is a lightweight, movable pointer to a commit (see How Git Works). Branching lets you develop features, fixes, and experiments in isolation without disturbing main.

Creating and switching branches

git branch                       # list local branches
git branch -a                    # list local + remote-tracking branches
git branch feature-x              # create a branch (doesn't switch to it)
git switch feature-x              # switch to it
git switch -c feature-x           # create + switch in one step
git checkout feature-x            # older equivalent of switch
git checkout -b feature-x         # older equivalent of switch -c

switch and restore (Git 2.23+) split checkout’s overloaded responsibilities — changing branches vs. discarding file changes — into two clearer commands. Both still work; newer tutorials favor switch.

Renaming and deleting branches

git branch -m old-name new-name    # rename
git branch -d feature-x            # delete (fails if unmerged)
git branch -D feature-x            # force delete

Merging

Merge a branch into whichever branch you currently have checked out:

git switch main
git merge feature-x

Git performs one of two kinds of merge depending on history:

  • Fast-forward — if main hasn’t moved since feature-x branched off, Git just moves the main pointer forward to feature-x’s tip. No new commit is created. Force a real merge commit anyway with git merge --no-ff feature-x to keep an explicit record that a feature branch existed.
  • Three-way merge — if both branches have diverged, Git compares the two tips against their common ancestor and creates a new merge commit with two parents, combining both histories.

Resolving conflicts

A conflict happens when the same region of a file was changed differently on both branches. Git pauses the merge and marks the file:

<<<<<<< HEAD
your version of the line
=======
their version of the line
>>>>>>> feature-x
  1. Open each conflicted file and edit it down to the content you want, removing the <<<<<<</=======/>>>>>>> markers.
  2. git add the resolved file(s).
  3. git commit to finish the merge (Git pre-fills a merge commit message).

Useful commands while resolving:

git status                    # lists conflicted files
git diff                      # shows conflict markers in context
git merge --abort             # bail out and return to pre-merge state
git checkout --ours <file>    # take your side entirely for one file
git checkout --theirs <file>  # take their side entirely for one file

Choosing a branching strategy

ModelIdea
Trunk-basedEveryone commits small changes to main frequently, guarded by feature flags and CI
GitHub FlowShort-lived feature branches → pull request → merge to main → deploy
Git FlowLong-lived develop and main, plus feature/, release/, and hotfix/ branches

Most modern teams use trunk-based development or GitHub Flow; Git Flow’s extra ceremony is mostly reserved for projects that ship multiple long-supported release versions in parallel.

See also: Rebasing & Cherry-Picking for an alternative to merge commits that keeps history linear.