Mastering Git for Production: Branching, Merging & Squash Strategies Every Engineer Should Know
Source: Dev.to
Modern Software Development & Git Basics
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
| Step | Command | Purpose | Outcome |
|---|---|---|---|
| 1️⃣ | mkdir git-merge-lab | Create a project folder, establishing an isolated workspace that prevents interference with existing files and ensures a controlled environment for Git‑merge practice. | A new directory named git-merge-lab is created. |
| 2️⃣ | cd git-merge-lab | Navigate the terminal session into the project directory, setting the folder as the current working environment. | The shell’s working directory is now git-merge-lab. |
| 3️⃣ | git init | Initialize a new Git repository. | A hidden .git folder is created; the directory is now a Git repo. |
| 4️⃣ | echo "# Team Project" > README.md | Create a README.md file and populate it with initial content. | A README file containing # Team Project is added to the folder. |
| 5️⃣ | git add README.md | Stage the file for the next commit. | The file is placed in the index (staging area). |
| 6️⃣ | git commit -m "Initial commit" | Record a snapshot of the project state in the repository history. | A commit with the message “Initial commit” is created. |
| 7️⃣ | git branch -M main | Rename the default branch to main. | The current branch is now named main. |
FAST‑FORWARD MERGE – Part 2
| Step | Command | Purpose | Outcome |
|---|---|---|---|
| 8️⃣ | git checkout -b feature-login | Create a new feature-login branch and switch to it. | A new branch feature-login is created off main and checked out. |
| 9️⃣ | echo "Login page created" > login.txt | Add a source file associated with the login functionality. | login.txt is created with the text Login page created. |
| 🔟 | git add login.txtgit commit -m "Add login feature" | git add stages the file; git commit records the staged change as a new snapshot. | A commit titled “Add login feature” appears on feature-login. |
| 1️⃣1️⃣ | git checkout main | Switch back to the main branch. | Working directory now reflects main. |
| 1️⃣2️⃣ | git merge feature-login | Perform a fast‑forward merge: main advances its pointer to incorporate the commits from feature-login. | main now contains the login feature; feature-login can be deleted if desired. |
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"
Creates an isolated development context for the profile 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"
Now the codebase has diverged: two independent branches (feature‑profile and feature‑settings) each contain distinct commits.
15️⃣ Merge Profile into main
git checkout main
git merge feature-profile
Fast‑forward or regular merge (depending on history) integrates the profile work.
16️⃣ Merge Settings (3‑Way) into main
git checkout main
git merge feature-settings
Because main already contains changes from feature‑profile, Git creates a merge commit that reconciles the two histories.
Note: When the merge editor (Vim by default) opens, type your commit message, press Esc, then type
:wqto write and quit.
| Step | Command | Purpose | Outcome |
|---|---|---|---|
| 16️⃣ | git merge feature-settings | Generate a merge commit that combines divergent histories from feature‑profile and feature‑settings. | main now contains a merge commit with both features. |
MERGE CONFLICT – Part 4
17️⃣ Bug‑Fix Branch (updates 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 Branch (also updates 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 cannot automatically merge the two divergent changes to README.md and halts the operation.
20️⃣ Resolve Conflict
-
Open the conflicted file in Vim (or your editor of choice):
vim README.md -
Remove the conflict markers (
>>>>>>>,<<<<<<<,=======) and keep the desired final content:# Awesome Team Project Version 2 -
Save & quit (
:wq). -
Stage the resolved file and commit the resolution:
git add README.md git commit -m "Resolve merge conflict"
| Step | Command | Purpose | Outcome |
|---|---|---|---|
| 20️⃣ | git add README.mdgit commit -m "Resolve merge conflict" | Record the manual conflict resolution in the repository history. | Conflict is resolved; main now contains the merged README. |
SQUASH MERGE – Part 5
21️⃣ Create Feature with Many Commits & Squash It
git checkout -b feature-dashboard
| Commit | Command |
|---|---|
| Add dashboard layout | bash\n echo "Dashboard layout" > dashboard.txt\n git add dashboard.txt\n git commit -m "Add dashboard layout"\n |
| Add charts | bash\n echo "Add charts" >> dashboard.txt\n git add dashboard.txt\n git commit -m "Add charts"\n |
| Fix alignment | bash\n echo "Fix alignment" >> dashboard.txt\n git add dashboard.txt\n git commit -m "Fix alignment"\n |
Now squash the three commits into a single, clean commit before merging back to main:
# Ensure you are on the feature branch
git checkout feature-dashboard
# Interactive rebase to squash the last three commits
git rebase -i HEAD~3
In the editor that opens:
- Change the word pick to s (or squash) for the second and third lines.
- Save & quit (
:wq).
Git will combine the three commits into one. Edit the final commit message if desired, then save & quit again.
Merge the squashed feature back to main
git checkout main
git merge --no-ff feature-dashboard # creates a merge commit even though fast‑forward is possible
Summary
| Concept | Typical Command(s) | When to Use |
|---|---|---|
| Create a branch | git checkout -b <branch> | Start isolated work. |
| Fast‑forward merge | git merge <branch> (when no divergent history) | Simple linear integration. |
| 3‑way merge | git merge <branch> (when histories diverge) | Combine parallel work. |
| Resolve conflicts | Edit conflicted files → git add <file> → git commit | When Git cannot auto‑merge. |
| Squash commits | git rebase -i HEAD~N → squash | Clean up noisy history before merging. |
| Push to remote | git push origin <branch> | Share work on GitHub/GitLab, etc. |
You now have a complete, step‑by‑step guide for creating branches, merging (fast‑forward, 3‑way, and squash), handling conflicts, and preparing a project for push to a remote repository. Happy coding!
22. View History
git log --oneline --graph --all
This command lets you 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 before 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
Closing Note
Branching, merging, and squashing form the backbone of efficient Git workflows.
- Branching enables safe experimentation.
- Merging integrates work.
- 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. In modern DevOps environments—where automation, rapid releases, and distributed teams are the norm—these practices are foundational to high‑quality software delivery.