Modern software development depends heavily on version control systems to manage code changes, support collaboration, and maintain stability. Git is the industry-standard distributed version control system that enables teams to work concurrently without overwriting each other’s progress.
Core to Git’s power are its branching and history management capabilities specifically branching, merging, squashing, and rebasing. Understanding these concepts is essential for maintaining a clean, traceable, and production ready codebase.
By the end of this article, engineers will understand how to:
Create branches to work safely
Merge branches using different strategies
Fix merge conflicts
Squash many commits into one
Push a complete project to GitHub
PROJECT SETUP -Part 1
1. Create Project Folder
mkdir git-merge-lab

This creates a new, empty directory named git-merge-lab, establishing an isolated workspace that prevents interference with existing files and ensures a controlled environment for Git merge practice.
2. Enter the Folder
cd git-merge-lab
This navigates the terminal session into the project directory, setting the folder as the current working environment.
Purpose:
Git operations are context-sensitive and can only be executed within an initialized repository or project directory.
Outcome:
All subsequent files, commits, and version control activities will be contained within this directory, ensuring organized project structure and traceability.
3. Initialize Git
git init

This Initializes the directory as a Git repository by generating a hidden .git subdirectory that stores metadata, configuration settings, and the complete version history.
Purpose:
Repository initialization is required for Git to begin tracking file changes and managing version control.
Outcome:
The directory is now under Git management, enabling change tracking, staging, committing, and collaboration workflows.
4. Create README File
echo "# Team Project" > README.md
This creates a README.md file and populates it with initial content.
Purpose:
Git requires at least one tracked file to generate a commit and establish version history within the repository.
Outcome:
The README.md file is present in the working directory but remains untracked until it is staged and committed to the repository.
5. Stage the File
git add README.md

This stages the file for inclusion in the upcoming commit by adding it to the Git index.
Purpose:
Git only records changes that have been explicitly staged, allowing developers to control which modifications are captured in a commit.
Outcome:
README.md is now in the staging area and prepared to be committed to the repository history.
6. Commit the File
git commit -m "Initial commit"
This creates a commit that captures a snapshot of the project state within the repository history.
Purpose:
Committing establishes a restore point, enabling version rollback and facilitating traceability if future changes introduce issues.
Outcome:
The repository now contains its initial commit, marking the first recorded version of the project.
7. Rename Branch to main
git branch -M main

This renames the active branch to main, aligning it with modern repository naming conventions.
Purpose:
Most hosting platforms and enterprise workflows designate main as the default branch, promoting consistency across development environments.
Outcome:
The primary development branch is now labeled main, serving as the central integration point for future changes.
FAST-FORWARD MERGE -Part 2
8. Create Feature Branch
git checkout -b feature-login

This creates a new Git branch and checks it out as the active working branch.
Purpose:
Feature development is isolated in dedicated branches to prevent instability in the main (or production) branch and to support controlled integration workflows.
Outcome:
The working directory is now tracking the feature-login branch instead of main, ensuring all subsequent commits apply only to this feature stream.
9. Add Feature File
echo "Login page created" > login.txt
This creates a new source file associated with the login functionality.
Purpose:
This step represents the introduction of new application logic and simulates the implementation of a feature within the codebase.
10. Commit Feature
git add login.txt
git commit -m "Add login feature"
Purpose of both commands:
git add stages the modified file by placing it into the index, preparing it for version control tracking.
git commit records the staged changes into the repository history as a new snapshot.
Outcome:
The feature changes are now securely versioned and stored within the feature branch’s commit history.
11. Switch Back to Main
git checkout main
This switches the working context back to the main branch.
Purpose:
In Git, merge operations are executed into the currently checked-out branch, so you must be on the target branch before initiating a merge.
12. Merge Feature (Fast-Forward)
git merge feature-login
The main branch advances its pointer to incorporate the commits from the feature branch.
Purpose:
Since main has not diverged and contains no new commits since the branch was created, Git performs a fast-forward merge rather than generating an additional merge commit.
3-WAY MERGE (PARALLEL WORK) -Part 3
13. Create Profile Feature
git checkout -b feature-profile
echo "Profile page created" > profile.txt
git add profile.txt
git commit -m "Add profile feature"
This establishes an isolated development context that allows a new feature to be implemented independently, without impacting the stability or history of other branches.
Note;
git checkout main switches the working directory to the main branch, ensuring the new work is based on the latest stable code.
git checkout -b feature-settings creates a new branch named feature-settings from main and immediately switches to it. These isolates feature development from the main codebase.
echo "Settings page created" > settings.txt creates a new file called settings.txt and writes initial content to it, representing the implementation of the settings feature.
git add settings.txt stages the newly created file by adding it to the Git index, marking it for inclusion in the next commit.
git commit -m "Add settings feature" creates a commit that records the staged changes in the repository history with a descriptive message, capturing the initial implementation of the settings feature.
14. Create Settings Feature
git checkout main
git checkout -b feature-settings
echo "Settings page created" > settings.txt
git add settings.txt
git commit -m "Add settings feature"
At this point, the codebase has diverged, with independent changes introduced on two separate branches, resulting in distinct commit histories.
15. Merge Profile
git checkout main
git merge feature-profile

This ensures the main branch is updated first with the profile feature, establishing it as the authoritative baseline before integrating additional feature work.
16. Merge Settings (3-Way)
git merge feature-settings
Note;
Demonstrates familiarity with the Vim editor by entering a commit message within the Vim interface and exiting correctly using the Esc key followed by :wq to write and quit.

Git generates a merge commit that reconciles and combines the divergent commit histories from both branches.
Outcome:
The main and feature branches have progressed independently, resulting in non-linear histories that require an explicit merge commit to integrate their changes.
MERGE CONFLICT -PART 4
17. Bugfix Changes README
git checkout -b bugfix-title
echo "# Team Project Version 2" > README.md
git add README.md
git commit -m "Update title in bugfix"
18. Feature Also Changes README
git checkout main
git checkout -b feature-title-update
echo "# Awesome Team Project" > README.md
git add README.md
git commit -m "Update title in feature"
19. Trigger Conflict
git checkout main
git merge bugfix-title
git merge feature-title-update
Git is unable to automatically complete the merge process and halts the operation.
Outcome:
Conflicting changes exist, and Git cannot determine which version should be applied, requiring manual conflict resolution by the developer.
20. Resolve Conflict
Open README.md delete the conflict marker and write the following command.
Note: Merge conflicts must be resolved manually by the developer. To do this, open the affected file in the Vim editor using vim README.md, review the conflict markers, and explicitly select or reconcile the appropriate changes.
# Awesome Team Project Version 2
Then:
git add README.md
git commit -m "Resolve merge conflict"

This notifies Git that the merge conflict has been resolved and the finalized version of the file has been saved by staging the corrected file for commit.
SQUASH MERGE -PART 5
21. Create Feature With Many Commits & Squash It
git checkout -b feature-dashboard
-
echo "Dashboard layout" > dashboard.txt
git add dashboard.txt
git commit -m "Add dashboard layout"
echo "Add charts" >> dashboard.txt
git add dashboard.txt
git commit -m "Add charts"
echo "Fix alignment" >> dashboard.txt
git add dashboard.txt
git commit -m "Fix alignment"
git checkout main
git merge --squash feature-dashboard
git commit -m "Add dashboard feature"

Squashing is used to consolidate multiple incremental development commits into a single, cohesive commit, ensuring that the main branch history remains clean, concise, and focused on meaningful changes rather than granular development steps.
22. View History
git log --oneline --graph --all
This is to visually inspect and validate the type of merge performed, ensuring the resulting commit history aligns with the intended integration strategy.
PUSH TO GITHUB -PART 6
23. Create Repo on GitHub
A remote repository must be created and accessible prior to performing a push operation, as Git requires a valid remote endpoint to receive and store the local commits.
DO NOT check: Add README, Add .gitignore
24. Connect Local to GitHub
git remote add origin https://github.com/YOUR_USERNAME/git-merge-lab.git
This defines the remote endpoint, informing Git of the destination repository to which local commits and branches should be transmitted.
25. Push All Branches
git push -u origin --all

This Pushes all local branches (such as main, feature, and bugfix) to the remote GitHub repository and establishes upstream tracking relationships, enabling simplified and consistent push and pull operations in subsequent workflows.

Branching, merging, and squashing form the backbone of efficient Git workflows. Branching enables safe experimentation, merging integrates work and squashing keeps history readable. Mastering when and how to use each technique allows engineering teams to scale collaboration while maintaining a stable and maintainable codebase.
For modern DevOps environments where automation, rapid releases, and distributed teams are the norm these practices are not optional, they are foundational to high quality software delivery.


















Top comments (0)