{"id":3656,"date":"2025-02-11T12:08:14","date_gmt":"2025-02-11T11:08:14","guid":{"rendered":"https:\/\/nguenkam.com\/blog\/?p=3656"},"modified":"2025-02-11T13:30:59","modified_gmt":"2025-02-11T12:30:59","slug":"understanding-git-merge-vs-rebase-a-deep-dive-into-branch-management","status":"publish","type":"post","link":"https:\/\/nguenkam.com\/blog\/index.php\/2025\/02\/11\/understanding-git-merge-vs-rebase-a-deep-dive-into-branch-management\/","title":{"rendered":"Understanding Git Merge vs Rebase: A Deep Dive into Branch Management"},"content":{"rendered":"\n<p>Git offers different approaches to integrating changes from one branch into another. Two of the most common methods are <code>merge<\/code> and <code>rebase<\/code>. In this article, we&#8217;ll explore their differences, use cases, and impact on your development workflow.<\/p>\n\n\n\n<h4>Initial Scenario<\/h4>\n\n\n\n<p>Let&#8217;s start with a common development situation:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"758\" height=\"89\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image.png\" alt=\"\" class=\"wp-image-3657\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image.png 758w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-300x35.png 300w\" sizes=\"(max-width: 758px) 100vw, 758px\" \/><\/figure>\n\n\n\n<p>Where:<\/p>\n\n\n\n<ul><li>A, B, C represent commits on the master branch<\/li><li>D, E represent commits on the feature branch<\/li><\/ul>\n\n\n\n<h4><span class=\"has-inline-color has-luminous-vivid-orange-color\"><strong>Method 1: Git Merge<\/strong><\/span><\/h4>\n\n\n\n<p>When we merge a feature branch into master, Git creates a new commit that combines the histories of both branches.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"759\" height=\"112\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-1.png\" alt=\"\" class=\"wp-image-3658\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-1.png 759w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-1-300x44.png 300w\" sizes=\"(max-width: 759px) 100vw, 759px\" \/><\/figure>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Result:<\/span><\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"762\" height=\"72\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-2.png\" alt=\"\" class=\"wp-image-3659\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-2.png 762w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-2-300x28.png 300w\" sizes=\"(max-width: 762px) 100vw, 762px\" \/><\/figure>\n\n\n\n<h4>Effects of Merge:<\/h4>\n\n\n\n<ul><li>Creates a new merge commit (M)<\/li><li>Preserves complete history<\/li><li>Maintains original timeline<\/li><li>Easy to revert<\/li><li>Can lead to a &#8220;messy&#8221; git graph<\/li><\/ul>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-luminous-vivid-orange-color\"><strong>Method 2: Git Rebase<\/strong><\/span><\/h4>\n\n\n\n<p>Rebasing rewrites the feature branch history by creating new commits on top of the target branch.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"760\" height=\"112\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-3.png\" alt=\"\" class=\"wp-image-3660\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-3.png 760w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-3-300x44.png 300w\" sizes=\"(max-width: 760px) 100vw, 760px\" \/><\/figure>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">Result:<\/span><\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"774\" height=\"74\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-4.png\" alt=\"\" class=\"wp-image-3661\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-4.png 774w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-4-300x29.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-4-768x73.png 768w\" sizes=\"(max-width: 774px) 100vw, 774px\" \/><\/figure>\n\n\n\n<h4>Effects of Rebase:<\/h4>\n\n\n\n<ul><li>Rewrites commits D and E (becoming D&#8217; and E&#8217;)<\/li><li>Creates linear history<\/li><li>Changes original commit timestamps<\/li><li>Cleaner git graph<\/li><li>More complex to revert<\/li><\/ul>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Impact on Pipeline and Workflow<\/h4>\n\n\n\n<h5>Merge Advantages<\/h5>\n\n\n\n<ul><li>? Safe for public branches<\/li><li>? Preserves complete history<\/li><li>? No conflicts with other developers<\/li><li>? Clear indication of where feature branches were integrated<\/li><\/ul>\n\n\n\n<h5>Merge Disadvantages<\/h5>\n\n\n\n<ul><li>? Can lead to a cluttered git graph<\/li><li>? Merge commits can &#8220;pollute&#8221; history<\/li><li>? Can make it harder to understand project history<\/li><\/ul>\n\n\n\n<h5>Rebase Advantages<\/h5>\n\n\n\n<ul><li>? Clean, linear history<\/li><li>? Easier to understand<\/li><li>? No additional merge commits<\/li><li>? Makes following the project history simpler<\/li><\/ul>\n\n\n\n<h5>Rebase Disadvantages<\/h5>\n\n\n\n<ul><li>? Dangerous for public branches<\/li><li>? Can cause issues if others have cloned the repository<\/li><li>? Conflict resolution can be more complex<\/li><li>? Loss of context about when features were integrated<\/li><\/ul>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Best Practices<\/h4>\n\n\n\n<h5>Use Merge When:<\/h5>\n\n\n\n<ol><li>Working on a public branch<\/li><li>Feature branch history is important<\/li><li>Collaborating with multiple developers on the same feature<\/li><li>You want to preserve the context of when features were integrated<\/li><\/ol>\n\n\n\n<h5>Use Rebase When:<\/h5>\n\n\n\n<ol><li>Working on a local, private branch<\/li><li>You prefer a clean, linear history<\/li><li>You want to ensure your feature branch is up-to-date<\/li><li>You&#8217;re working alone on a feature<\/li><\/ol>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5><span class=\"has-inline-color has-luminous-vivid-orange-color\">Important Note on Force Push<\/span><\/h5>\n\n\n\n<p>When using rebase on an already pushed branch, we&#8217;ll need to force push:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git push --force-with-lease\n<\/code><\/pre>\n\n\n\n<p>?? <strong>Warning<\/strong>: Use force push with caution as it rewrites history for other developers.<\/p>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Code Examples in Practice<\/h4>\n\n\n\n<h5>Merge Workflow<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code># Start feature branch\ngit checkout -b feature\/new-feature master\n\n# Make changes and commit\ngit add .\ngit commit -m \"Add new feature\"\n\n# Later, merge back to master\ngit checkout master\ngit merge feature\/new-feature\n<\/code><\/pre>\n\n\n\n<h5>Rebase Workflow<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code># Start feature branch\ngit checkout -b feature\/new-feature master\n\n# Make changes and commit\ngit add .\ngit commit -m \"Add new feature\"\n\n# Keep feature branch up to date\ngit checkout feature\/new-feature\ngit rebase master\n\n# When ready to merge\ngit checkout master\ngit merge feature\/new-feature # Will be a fast-forward merge\n<\/code><\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4><span class=\"has-inline-color has-vivid-cyan-blue-color\">A Practical Example with Real Commit History<\/span><\/h4>\n\n\n\n<p>Let&#8217;s look at a concrete example showing exactly what happens during merge and rebase operations.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># On master branch\n$ git log --oneline\n7890abc Fix navbar responsiveness    # C\n456def2 Update user authentication   # B\n123abcd Initial commit              # A\n\n# On feature\/auth branch\n$ git log --oneline\nef98765 Add OAuth integration       # E\ncd45678 Add login form             # D\n456def2 Update user authentication  # B\n123abcd Initial commit             # A\n<\/code><\/pre>\n\n\n\n<p>Visual representation:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"771\" height=\"79\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-5.png\" alt=\"\" class=\"wp-image-3664\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-5.png 771w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-5-300x31.png 300w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-5-768x79.png 768w\" sizes=\"(max-width: 771px) 100vw, 771px\" \/><\/figure>\n\n\n\n<h5><strong><span class=\"has-inline-color has-vivid-green-cyan-color\">Scenario 1: Merge Process<\/span><\/strong><\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git checkout master\n$ git merge feature\/auth\n<\/code><\/pre>\n\n\n\n<h5>Result after merge:<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git log --oneline\n9876543 Merge branch 'feature\/auth' into master  # Merge commit (M)\n7890abc Fix navbar responsiveness                # C\nef98765 Add OAuth integration                    # E\ncd45678 Add login form                          # D\n456def2 Update user authentication              # B\n123abcd Initial commit                          # A\n<\/code><\/pre>\n\n\n\n<h5>Visual representation:<\/h5>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"755\" height=\"79\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-6.png\" alt=\"\" class=\"wp-image-3665\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-6.png 755w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-6-300x31.png 300w\" sizes=\"(max-width: 755px) 100vw, 755px\" \/><\/figure>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-green-cyan-color\"><strong>Scenario 2: Rebase Process<\/strong><\/span><\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git checkout feature\/auth\n$ git rebase master\n<\/code><\/pre>\n\n\n\n<h5>During rebase:<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code># Git internally performs these steps:\n1. Temporarily stores changes from D and E\n2. Moves feature branch pointer to master's HEAD (7890abc)\n3. Replays commits D and E one by one<\/code><\/pre>\n\n\n\n<h5>Result after rebase:<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git log --oneline\nab12345 Add OAuth integration       # E' (new hash)\nde34567 Add login form             # D' (new hash)\n7890abc Fix navbar responsiveness   # C\n456def2 Update user authentication  # B\n123abcd Initial commit             # A\n<\/code><\/pre>\n\n\n\n<h5>Visual representation:<\/h5>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"768\" height=\"56\" src=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-7.png\" alt=\"\" class=\"wp-image-3666\" srcset=\"https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-7.png 768w, https:\/\/nguenkam.com\/blog\/wp-content\/uploads\/2025\/02\/image-7-300x22.png 300w\" sizes=\"(max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\"><strong>Detailed Analysis of Changes<\/strong><\/span><\/h5>\n\n\n\n<h5>Original Commits (Before Rebase):<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code># Commit D details\n$ git show cd45678\ncommit cd45678...\nAuthor: John Doe\nDate:   Mon Feb 10 10:00:00 2025 +0100\n    Add login form\n    \n    - Added login form component\n    - Added form validation\n    ...\n\n# Commit E details\n$ git show ef98765\ncommit ef98765...\nAuthor: John Doe\nDate:   Mon Feb 10 11:00:00 2025 +0100\n    Add OAuth integration\n    \n    - Implemented OAuth2 flow\n    - Added social login buttons\n    ...\n<\/code><\/pre>\n\n\n\n<h5>New Commits After Rebase (D&#8217; and E&#8217;):<\/h5>\n\n\n\n<pre class=\"wp-block-code\"><code># New Commit D' details\n$ git show de34567\ncommit de34567...\nAuthor: John Doe\nDate:   Mon Feb 11 14:30:00 2025 +0100  # Note the new timestamp\n    Add login form\n    \n    - Added login form component\n    - Added form validation\n    ...\n\n# New Commit E' details\n$ git show ab12345\ncommit ab12345...\nAuthor: John Doe\nDate:   Mon Feb 11 14:30:01 2025 +0100  # Note the new timestamp\n    Add OAuth integration\n    \n    - Implemented OAuth2 flow\n    - Added social login buttons\n    ...\n<\/code><\/pre>\n\n\n\n<h5><span class=\"has-inline-color has-vivid-red-color\"><strong>Key Observations<\/strong><\/span><\/h5>\n\n\n\n<ol><li><strong>Commit Hash Changes:<\/strong><ul><li>Original feature commits:&nbsp;<code>cd45678<\/code>&nbsp;and&nbsp;<code>ef98765<\/code><\/li><li>New rebased commits:&nbsp;<code>de34567<\/code>&nbsp;and&nbsp;<code>ab12345<\/code><\/li><\/ul><\/li><li><strong>Timestamp Changes:<\/strong><ul><li>Original commits: Feb 10, 2025<\/li><li>Rebased commits: Feb 11, 2025 (current rebase time)<\/li><\/ul><\/li><li><strong>Content Changes:<\/strong><ul><li>The commit messages and changes remain the same<\/li><li>Only the metadata (commit hash, timestamp) changes<\/li><\/ul><\/li><li><strong>Branch Structure:<\/strong><ul><li>Before: Branching history visible<\/li><li>After: Linear history<\/li><\/ul><\/li><\/ol>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4>Common Commands to View These Changes<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code># View complete graph\n$ git log --graph --oneline --all\n\n# View detailed commit information\n$ git show &lt;commit-hash&gt;\n\n# View branch structure\n$ git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&lt;%an&gt;%Creset' --abbrev-commit\n<\/code><\/pre>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h5>Conclusion<\/h5>\n\n\n\n<p>Both merge and rebase have their place in Git workflows. The choice between them depends on our specific needs:<\/p>\n\n\n\n<ul><li>Choose&nbsp;<strong>merge<\/strong>&nbsp;for maintaining history and working with public branches<\/li><li>Choose&nbsp;<strong>rebase<\/strong>&nbsp;for a clean, linear history and private feature development<\/li><\/ul>\n\n\n\n<p>Remember that these aren&#8217;t mutually exclusive &#8211; many teams use both approaches depending on the situation. The key is understanding the implications of each method and choosing the right tool for our specific scenario.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Git offers different approaches to integrating changes from one branch into another. Two of the most common methods are merge and rebase. In this article, we&#8217;ll explore their differences, use cases, and impact on your development workflow. Initial Scenario Let&#8217;s start with a common development situation: Where: A, B, C represent commits on the master [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":807,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[60],"tags":[495,494,971],"_links":{"self":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3656"}],"collection":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=3656"}],"version-history":[{"count":4,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3656\/revisions"}],"predecessor-version":[{"id":3669,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/posts\/3656\/revisions\/3669"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media\/807"}],"wp:attachment":[{"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=3656"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=3656"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nguenkam.com\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=3656"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}