| |

LFCA 88 ๐Ÿง Git Branching โ€” Basics

Every Git repository has at least one branch. It is called main in modern repositories and master in older ones. The branch is a movable pointer to a commit. When you commit, the branch pointer moves forward to the new commit. When you create a new branch, you create a new pointer. When you switch branches, Git changes which pointer is the current one and updates the working directory to match.

The LFCA exam places Git under DevOps Fundamentals, which carries 12โ€“16% of the total weight. The study plan lists “Git Concepts” as a core DevOps topic. Branching is the mechanism that makes Git’s workflow possible: multiple developers working on different features without interfering with each other, and a main branch that remains stable throughout.

Key point: A branch in Git is not a copy of the files. It is a lightweight pointer to a commit. Creating a branch is instant because it only writes a 41-byte file that contains the SHA-1 hash of the commit. Switching branches changes the working directory to match the commit the branch points to. The lightness of branches is what makes Git’s branching model fast and flexible.


Why branching matters

A branch is an independent line of development. It allows a developer to work on a feature without affecting the main branch. It allows a team to experiment with an idea without committing to it. It allows a bug to be fixed on a stable branch while a new feature is being developed on another.

The isolation problem. Without branches, all developers work on the same line. A half-finished feature blocks the release of a bug fix. A broken experiment breaks the main branch. Branches isolate the work. The main branch stays stable. The feature branch is where the unfinished work lives.

The release problem. A release is a specific version of the code. The v1.0 release should be frozen while the team works on v1.1. A branch is the mechanism for freezing a version. The release branch is created from the main branch at the release point. The team continues to work on the main branch. The release branch is only updated with bug fixes.

The experimentation problem. A developer has an idea. They do not know if it will work. A branch lets them try without risk. If the idea works, the branch is merged. If it fails, the branch is deleted. The main branch is never affected.

The parallel work problem. Two developers work on two different features. Each has their own branch. Neither blocks the other. When the features are complete, the branches are merged into the main branch. The merge combines the changes.

The trade-off. Branches introduce the merge. A merge combines the changes from two branches. If the branches have changed the same lines of the same file, a conflict occurs. The developer resolves the conflict manually. The conflict is the price of parallel work. The alternative is serial work, which is slower and more fragile.


a. Creating a Branch

The git branch command creates a new branch. The branch points to the current commit. The working directory is not changed.

git branch feature/login

The command creates a new branch named feature/login that points to the same commit as the current branch. The current branch is unchanged. The HEAD still points to the current branch.

To list the branches:

git branch

The output shows the branches with an asterisk next to the current one:

* main
  feature/login

To list the branches with their last commit:

git branch -v

The output shows the commit hash and message for each branch.

The git checkout -b command creates a branch and switches to it in a single step:

git checkout -b feature/login

The command is equivalent to:

git branch feature/login
git checkout feature/login

The git switch -c command is the modern equivalent:

git switch -c feature/login

The git switch command is the modern replacement for git checkout. It is more focused: git switch changes branches, git restore restores files. The git checkout command is older and does both. The LFCA exam may test either.


b. Switching Branches

The git checkout command switches to a different branch. The working directory is updated to match the commit the branch points to.

git checkout feature/login

The output shows the switch:

Switched to branch 'feature/login'

The git switch command is the modern equivalent:

git switch feature/login

When switching branches, Git checks whether the working directory has uncommitted changes. If the changes do not conflict with the target branch, Git carries them over. If the changes conflict, Git refuses to switch and prompts the developer to commit or stash the changes.

The git checkout - command switches to the previous branch:

git checkout -

The command is useful for switching back and forth between two branches.

When switching to a branch that does not exist locally but exists on the remote, Git creates a local branch that tracks the remote branch:

git checkout feature/login

If origin/feature/login exists and feature/login does not, Git creates the local branch and sets it to track the remote branch.


c. Merging Branches

The git merge command combines the changes from one branch into another. The branch that receives the changes is the current branch. The branch that provides the changes is the argument.

git checkout main
git merge feature/login

The command merges feature/login into main. The main branch is the current branch. The feature/login branch is the source.

There are two types of merges.

Fast-forward merge. If the current branch has not diverged from the source branch, Git simply moves the current branch pointer forward to the source branch’s commit. No merge commit is created.

Before:
main:     A โ”€โ”€> B
feature:  A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D

After fast-forward:
main:     A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D
feature:  A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D

Three-way merge. If the branches have diverged, Git creates a new commit that combines the changes from both branches. The new commit has two parents.

Before:
main:     A โ”€โ”€> B โ”€โ”€> E
feature:  A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D

After three-way merge:
main:     A โ”€โ”€> B โ”€โ”€> E โ”€โ”€> M
                    โ”‚       โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
feature:  A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D

The merge commit M has two parents: E (the previous main) and D (the feature branch).

If the branches have changed the same lines of the same file, a conflict occurs. Git marks the conflict in the file:

<<<<<<< HEAD
console.log('main version');
=======
console.log('feature version');
>>>>>>> feature/login

The developer edits the file to resolve the conflict, removes the markers, stages the resolved file, and commits the merge.

The --no-ff flag forces a merge commit even when a fast-forward is possible. The --ff-only flag refuses to merge if a fast-forward is not possible.

After the merge, the feature branch can be deleted:

git branch -d feature/login

The -d flag deletes the branch. The branch must be fully merged. The -D flag forces the deletion even if the branch is not merged.


Complete Example Session

This session creates a branch, makes commits on it, merges it back into the main branch, and handles a conflict.

# ============================================
# PART 1: THE INITIAL REPOSITORY
# ============================================

mkdir branching-demo
cd branching-demo
git init -b main

echo "# Project" > README.md
git add README.md
git commit -m "Initial commit"

# The repository has one branch (main) and one commit.

# ============================================
# PART 2: CREATE A BRANCH
# ============================================

git branch feature/login

git branch

# Output:
#   feature/login
# * main

# The branch is created.
# The current branch is still main.

# ============================================
# PART 3: SWITCH TO THE BRANCH
# ============================================

git checkout feature/login

# Output:
# Switched to branch 'feature/login'

# Or with git switch:
git switch feature/login

# ============================================
# PART 4: COMMIT ON THE BRANCH
# ============================================

echo "function login() { }" > login.js
git add login.js
git commit -m "Add login function"

echo "function logout() { }" >> login.js
git add login.js
git commit -m "Add logout function"

git log --oneline

# Output:
# c3d4e5f Add logout function
# b2c3d4e Add login function
# a1b2c3d Initial commit

# The branch has two new commits.
# The main branch is unchanged.

# ============================================
# PART 5: SWITCH BACK TO MAIN
# ============================================

git checkout main

ls

# Output:
# README.md

# The login.js file is not present.
# The working directory matches the main branch.

# ============================================
# PART 6: MAKE A COMMIT ON MAIN
# ============================================

echo "## Project" > README.md
git add README.md
git commit -m "Improve README"

# The main branch has a new commit.
# The branches have diverged.

# ============================================
# PART 7: MERGE THE FEATURE BRANCH
# ============================================

git merge feature/login

# Output:
# Merge made by the 'ort' strategy.
#  login.js | 1 +
#  1 file changed, 1 insertion(+)

# A merge commit is created.
# The merge commit has two parents.

git log --oneline --graph

# Output:
# *   d4e5f6g Merge branch 'feature/login'
# |\
# | * c3d4e5f Add logout function
# | * b2c3d4e Add login function
# * | e5f6g7h Improve README
# |/
# * a1b2c3d Initial commit

# ============================================
# PART 8: DELETE THE FEATURE BRANCH
# ============================================

git branch -d feature/login

# Output:
# Deleted branch feature/login (was c3d4e5f).

# The branch is deleted.
# The commits are still in the history.

# ============================================
# PART 9: HANDLE A MERGE CONFLICT
# ============================================

git checkout -b feature/new-readme

echo "# New Title" > README.md
git add README.md
git commit -m "Change README title"

git checkout main

echo "# Updated Title" > README.md
git add README.md
git commit -m "Update README title"

git merge feature/new-readme

# Output:
# Auto-merging README.md
# CONFLICT (content): Merge conflict in README.md
# Automatic merge failed; fix conflicts and then commit the result.

cat README.md

# Output:
# <<<<<<< HEAD
# # Updated Title
# =======
# # New Title
# >>>>>>> feature/new-readme

# The conflict is marked in the file.
# The developer must resolve it.

# ============================================
# PART 10: RESOLVE THE CONFLICT
# ============================================

echo "# Combined Title" > README.md
git add README.md
git commit -m "Merge feature/new-readme"

# The conflict is resolved.
# The merge commit is created.

git log --oneline --graph

# Output:
# *   h8i9j0k Merge feature/new-readme
# |\
# | * g7h8i9j Change README title
# * | f6e5d4c Update README title
# |/
# * e5f6g7h Improve README
# ...

The ten parts cover the initial repository, creating a branch, switching to the branch, committing on the branch, switching back to main, making a commit on main, merging the feature branch, deleting the feature branch, handling a merge conflict, and resolving the conflict.


Quick Reference

The Branch Commands

CommandPurpose
git branchList branches
git branch <name>Create a branch
git branch -vList with last commit
git branch -d <name>Delete a merged branch
git branch -D <name>Force delete a branch
git checkout <name>Switch to a branch
git checkout -b <name>Create and switch
git switch <name>Switch (modern)
git switch -c <name>Create and switch (modern)
git merge <name>Merge into current branch

The Merge Types

TypeWhenResult
Fast-forwardNo divergenceBranch pointer moves forward
Three-wayDivergedNew merge commit
ConflictSame lines changedManual resolution required

The Merge Flags

FlagPurpose
--no-ffForce a merge commit
--ff-onlyFail if not fast-forward
--squashCombine into one commit
--abortCancel the merge

The Conflict Markers

MarkerMeaning
<<<<<<< HEADStart of current branch’s version
=======Separator
>>>>>>> branchEnd of the other branch’s version

Best Practices

โœ… Do This:

# Use descriptive branch names
git checkout -b feature/user-authentication                     # โœ…
# Keep branches short-lived
# Merge within hours or days, not weeks.                         # โœ…
# Pull from main before merging
git checkout main && git pull                                    # โœ…
# Delete merged branches
git branch -d feature/login                                      # โœ…
# Resolve conflicts carefully
# Read both versions, then edit the file.                        # โœ…

โŒ Don’t Do This:

# Don't commit directly to main
git checkout main && git commit -m "quick fix"                   # โŒ
# Don't use vague branch names
git checkout -b stuff                                            # โŒ
# Don't force delete unmerged branches
git branch -D feature/login  # loses the work                    # โŒ
# Don't merge without pulling first
git merge feature/login  # may have conflicts                    # โš ๏ธ

Common Pitfalls

PitfallWhy It HappensFix
Cannot switch branchesUncommitted changes conflictCommit or stash first
Merge conflictSame lines changedResolve manually
Lost workForce deleted a branchUse git reflog to recover
Branch not trackingNo upstream setgit push -u origin branch
Merge commit unexpectedNo --ff-onlyUse --no-ff or --ff-only

Real-World Examples

1. Create a Branch

git checkout -b feature/login

2. List Branches

git branch -v

3. Switch Branch

git switch main

4. Switch to Previous

git checkout -

5. Merge a Branch

git checkout main && git merge feature/login

6. Fast-Forward Merge

git merge --ff-only feature/login

7. No-Fast-Forward Merge

git merge --no-ff feature/login

8. Delete a Branch

git branch -d feature/login

9. Resolve a Conflict

# Edit the file, then:
git add README.md
git commit -m "Merge feature/login"

10. Abort a Merge

git merge --abort

Visual

The Branch Pointer

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  BRANCH POINTER                              โ”‚
โ”‚                                              โ”‚
โ”‚  main โ”€โ”€> A โ”€โ”€> B โ”€โ”€> C                      โ”‚
โ”‚                                              โ”‚
โ”‚  git branch feature/login                    โ”‚
โ”‚       โ”‚                                      โ”‚
โ”‚       โ–ผ                                      โ”‚
โ”‚  main โ”€โ”€โ”€โ”€โ”€โ”                                 โ”‚
โ”‚            โ””โ”€> A โ”€โ”€> B โ”€โ”€> C                 โ”‚
โ”‚  feature  โ”€โ”€โ”˜                                โ”‚
โ”‚                                              โ”‚
โ”‚  Both branches point to C.                   โ”‚
โ”‚  The branch is a 41-byte file.               โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Fast-Forward Merge

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  FAST-FORWARD                                โ”‚
โ”‚                                              โ”‚
โ”‚  Before:                                     โ”‚
โ”‚  main:    A โ”€โ”€> B                            โ”‚
โ”‚  feature: A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D                โ”‚
โ”‚                                              โ”‚
โ”‚  git checkout main && git merge feature      โ”‚
โ”‚                                              โ”‚
โ”‚  After:                                      โ”‚
โ”‚  main:    A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D                โ”‚
โ”‚                                              โ”‚
โ”‚  The main pointer moves to D.                โ”‚
โ”‚  No merge commit is created.                 โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Three-Way Merge

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  THREE-WAY MERGE                             โ”‚
โ”‚                                              โ”‚
โ”‚  Before:                                     โ”‚
โ”‚  main:    A โ”€โ”€> B โ”€โ”€> E                      โ”‚
โ”‚  feature: A โ”€โ”€> B โ”€โ”€> C โ”€โ”€> D                โ”‚
โ”‚                                              โ”‚
โ”‚  git checkout main && git merge feature      โ”‚
โ”‚                                              โ”‚
โ”‚  After:                                      โ”‚
โ”‚  main:    A โ”€โ”€> B โ”€โ”€> E โ”€โ”€> M                โ”‚
โ”‚                     โ”‚       โ”‚                โ”‚
โ”‚                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                              โ”‚
โ”‚  M has two parents: E and D.                 โ”‚
โ”‚  M combines the changes from both.           โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Conflict

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  CONFLICT MARKERS                            โ”‚
โ”‚                                              โ”‚
โ”‚  <<<<<<< HEAD                                โ”‚
โ”‚  # Updated Title                             โ”‚
โ”‚  =======                                     โ”‚
โ”‚  # New Title                                 โ”‚
โ”‚  >>>>>>> feature/new-readme                  โ”‚
โ”‚                                              โ”‚
โ”‚  The developer edits the file.               โ”‚
โ”‚  The markers are removed.                    โ”‚
โ”‚  The file is staged.                         โ”‚
โ”‚  The merge is committed.                     โ”‚
โ”‚                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
BranchMovable pointer to a commit
Create branchgit branch <name>
Create and switchgit checkout -b <name>
Switchgit checkout <name>, git switch <name>
Mergegit merge <name>
Fast-forwardNo divergence, pointer moves
Three-wayDiverged, merge commit
ConflictSame lines changed
Delete branchgit branch -d <name>
Force deletegit branch -D <name>
LFCA weightDevOps Fundamentals, 12โ€“16%

Key takeaways:

  • A branch is a movable pointer to a commit. It is not a copy of the files. Creating a branch is instant because it only writes a 41-byte file that contains the SHA-1 hash of the commit .
  • The git branch command creates a branch; git checkout or git switch switches to it. The -b flag on git checkout and the -c flag on git switch create and switch in a single command .
  • A merge combines the changes from one branch into another. A fast-forward merge moves the branch pointer forward. A three-way merge creates a merge commit with two parents .
  • A conflict occurs when the same lines of the same file are changed in both branches. Git marks the conflict in the file. The developer resolves it manually, stages the resolved file, and commits the merge .
  • Branches should be short-lived. A branch that lives for weeks diverges from the main branch and becomes difficult to merge. A branch that lives for hours or days is easy to merge.
  • The main branch should remain stable. The developers work on feature branches. The feature branches are merged into the main branch when they are complete. The main branch is the source of truth.
  • Deleting a merged branch is safe. The commits are still in the main branch’s history. The -d flag deletes a merged branch. The -D flag forces the deletion even if the branch is not merged. The git reflog command can recover a deleted branch.

Remember: A branch is a pointer. Creating one is instant. Switching one changes the working directory. Merging one combines the changes. The branch is the mechanism that makes parallel work possible. The main branch stays stable. The feature branches are where the work happens. The merge is how the work enters the main branch. The conflict is the price of parallel work, and it must be resolved manually. The branch is the foundation of every Git workflow.


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!