When working on a frontend project, you'll often create separate branches for new features or bug fixes. Eventually, you'll need to integrate this work back into your main codebase. Git offers two primary ways to do this: merging and rebasing. Merging is like taking two divergent paths and bringing them back together by creating a new "merge commit." This merge commit explicitly records that two branches were combined, preserving the exact history of both. It's a non-destructive operation because it doesn't change existing commits, making it a safe and transparent way to integrate work, often preferred for bringing completed features into stable, shared branches like main or develop.
Rebasing, on the other hand, is about moving or "replaying" your branch's commits onto a new base commit. Instead of creating a merge commit, rebasing rewrites the history of your feature branch, making it appear as if you started your work from the latest point of the target branch. This results in a cleaner, more linear project history without extra merge commits. Imagine you're building a feature on top of an older version of main, and main has moved forward. Rebasing your feature branch onto the latest main updates your branch to that point, making it look like your changes were made directly after the very latest main commit.
So, when do you use each? Merge is generally preferred for integrating finished features into public, shared branches (like main or develop). It preserves the complete historical context, including when and where branches diverged. Use rebase when you want to keep your local feature branch up-to-date with the main branch before you eventually merge it, or when you want to clean up your own commits within your local feature branch before pushing them for review. Rebasing keeps your personal branch tidy and helps ensure your changes apply smoothly to the latest codebase. Crucially, never rebase a branch that has already been pushed to a shared remote repository and other developers are working on it, as this rewrites shared history and can cause significant problems for your team.
Key Takeaways
- Merging combines branch histories, creating a new "merge commit."
- Rebasing rewrites history by moving your commits to a new base, creating a linear history.
- Use
mergewhen integrating completed features into shared, public branches (main). - Use
rebaseto keep your local feature branch updated withmainor to clean up your own commits before pushing. - Never rebase public/shared branches that others are working on!
Code Example
# Example 1: Merging a feature branch into main
git checkout main # Switch to the main branch
git pull origin main # Get the latest changes from remote
git merge feature-branch-name # Merge your feature branch into main
git push origin main # Push the updated main branch
# Example 2: Rebasing a feature branch onto main (to update it)
git checkout feature-branch-name # Switch to your feature branch
git pull origin feature-branch-name # Get latest changes for your feature branch
git rebase main # Rebase your feature branch onto main
git push origin feature-branch-name --force-with-lease # Push rewritten history (use with caution!)How this code works
This code illustrates two distinct strategies for incorporating changes from a feature-branch-name into the main branch. The first set of commands demonstrates git merge, which combines development histories while preserving all original commits. It starts by using git checkout main and git pull origin main to ensure the local main branch is fully up-to-date. Then, git merge feature-branch-name integrates the feature branch's changes, typically creating a new "merge commit" on main. This merge commit explicitly shows when the feature branch was integrated, maintaining a clear record of parallel development. Finally, git push origin main sends these updated changes to the remote repository.
The second approach uses git rebase to integrate changes, aiming for a linear, cleaner project history. It begins by using git checkout feature-branch-name and git pull origin feature-branch-name to get the latest version of the feature branch. The core step, git rebase main, takes all commits from the feature-branch-name and reapplies them on top of the latest main branch commits. This effectively rewrites the feature branch's history, making it appear as if its development started from the current main. Because history is rewritten, a simple push won't work. The command git push origin feature-branch-name --force-with-lease is then required. This is a crucial safety measure; it forces the push to update the remote branch but checks that the remote hasn't been updated by someone else in the meantime, preventing accidental overwrites of their work.