{"id":71496,"date":"2026-03-22T20:58:25","date_gmt":"2020-09-29T18:07:07","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=71496"},"modified":"2026-03-22T20:58:26","modified_gmt":"2026-03-22T17:58:26","slug":"implement-new-feature-in-git-without-affecting-master-branch","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/implement-new-feature-in-git-without-affecting-master-branch\/","title":{"rendered":"Git Feature Branch Workflow &#8211; Develop Without Affecting Main"},"content":{"rendered":"\n<p>Feature branches are the backbone of collaborative Git workflows. They let you develop new functionality, fix bugs, or experiment &#8211; all without touching the main branch. Every change stays isolated until it is reviewed, tested, and merged.<\/p>\n\n\n\n<p>This guide covers the full feature branch workflow from creation to merge and cleanup. Whether your team follows GitHub Flow, Git Flow, or trunk-based development, the core branching mechanics are the same. We also compare merge strategies (merge commit vs rebase vs squash) and walk through conflict resolution. For a deeper look at <a href=\"https:\/\/computingforgeeks.com\/git-pr-vs-mr-vs-release-vs-rc-vs-tag-vs-branch\/\" target=\"_blank\" rel=\"noreferrer noopener\">Git terminology like PRs, MRs, tags, and branches<\/a>, check our reference guide.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before starting, make sure you have the following in place:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Git 2.x installed on your workstation &#8211; see our guide on <a href=\"https:\/\/computingforgeeks.com\/install-git-rhel-rocky-almalinux\/\" target=\"_blank\" rel=\"noreferrer noopener\">installing Git on RHEL \/ Rocky Linux \/ AlmaLinux<\/a><\/li>\n\n<li>A remote repository on GitHub, GitLab, or Bitbucket (or any Git hosting platform)<\/li>\n\n<li>Basic familiarity with Git commands (clone, commit, push)<\/li>\n\n<li>SSH key or HTTPS credentials configured for pushing to the remote<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Create a Feature Branch<\/h2>\n\n\n\n<p>Every new piece of work starts with a fresh branch off the main branch. This keeps your changes isolated and makes code review straightforward. First, make sure your local main branch is up to date with the remote.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout main\ngit pull origin main<\/code><\/pre>\n\n\n\n<p>Now create and switch to a new feature branch. Use a descriptive name that makes the purpose clear at a glance.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout -b feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>This creates the branch and switches to it in one step. You can verify which branch you are on with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git branch<\/code><\/pre>\n\n\n\n<p>The active branch is marked with an asterisk:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  main\n* feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p><strong>Branch naming conventions<\/strong> &#8211; pick a pattern your team agrees on and stick with it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>feature\/<\/code> &#8211; new functionality (feature\/add-oauth-login)<\/li>\n\n<li><code>bugfix\/<\/code> &#8211; bug fixes (bugfix\/fix-null-pointer-on-submit)<\/li>\n\n<li><code>hotfix\/<\/code> &#8211; urgent production fixes (hotfix\/patch-sql-injection)<\/li>\n\n<li><code>chore\/<\/code> &#8211; maintenance tasks (chore\/update-dependencies)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Make Changes and Commit<\/h2>\n\n\n\n<p>With the feature branch active, make your code changes as usual. The key difference is that all commits stay on this branch and do not affect main. Stage your modified files and commit with a clear message.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git add src\/auth\/login.py src\/auth\/middleware.py\ngit commit -m \"Add JWT-based login endpoint and auth middleware\"<\/code><\/pre>\n\n\n\n<p>Write commits that describe <strong>what<\/strong> changed and <strong>why<\/strong>, not just &#8220;fixed stuff.&#8221; Small, focused commits are easier to review and revert if something breaks. A good practice is to commit early and often rather than accumulating a massive diff.<\/p>\n\n\n\n<p>Continue making changes, staging, and committing as needed. You can check your commit history on the feature branch at any time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git log --oneline main..HEAD<\/code><\/pre>\n\n\n\n<p>This shows only the commits on your feature branch that are not on main:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>a3f7c2d Add JWT-based login endpoint and auth middleware\nb1e9f4a Add user model with password hashing\nc8d2a1b Create auth module structure<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Push Feature Branch to Remote<\/h2>\n\n\n\n<p>Once you have one or more commits on the feature branch, push it to the remote repository. This backs up your work and makes the branch visible to teammates.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git push -u origin feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>The <code>-u<\/code> flag sets the upstream tracking branch so future pushes from this branch only need <code>git push<\/code> without specifying the remote and branch name. After the first push, subsequent pushes are just:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git push<\/code><\/pre>\n\n\n\n<p>If your team uses a CI\/CD pipeline, pushing the branch typically triggers automated tests. Most teams configure pipelines to run on every push to feature branches so issues surface early. If you are running <a href=\"https:\/\/computingforgeeks.com\/install-jenkins-rocky-almalinux\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jenkins<\/a>, you can set up multi-branch pipelines that automatically detect and build new branches.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Create a Pull Request (GitHub \/ GitLab)<\/h2>\n\n\n\n<p>A pull request (PR on GitHub\/Bitbucket) or merge request (MR on GitLab) is the formal way to propose merging your feature branch into main. It provides a centralized place for code review, discussion, and CI status checks. For a comprehensive explanation of <a href=\"https:\/\/docs.github.com\/en\/pull-requests\/collaborating-with-pull-requests\/proposing-changes-to-your-work-with-pull-requests\/about-pull-requests\" target=\"_blank\" rel=\"noreferrer noopener\">pull requests and their lifecycle<\/a>, see the official GitHub documentation.<\/p>\n\n\n\n<p><strong>On GitHub<\/strong>, create a PR from the command line using the GitHub CLI:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gh pr create --base main --head feature\/add-user-authentication \\\n  --title \"Add user authentication with JWT\" \\\n  --body \"Implements login endpoint, auth middleware, and user model with password hashing.\"<\/code><\/pre>\n\n\n\n<p>Or navigate to your repository on GitHub and click &#8220;Compare &#038; pull request&#8221; after pushing the branch.<\/p>\n\n\n\n<p><strong>On GitLab<\/strong>, create a merge request via the CLI:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>glab mr create --source-branch feature\/add-user-authentication \\\n  --target-branch main \\\n  --title \"Add user authentication with JWT\"<\/code><\/pre>\n\n\n\n<p>When writing PR descriptions, include the context a reviewer needs &#8211; what problem it solves, what approach you took, how to test it, and any areas where you want specific feedback.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Code Review Workflow<\/h2>\n\n\n\n<p>Code review is where feature branches deliver their real value. The main branch stays protected while the team reviews changes in isolation. A solid review process catches bugs, enforces standards, and spreads knowledge across the team.<\/p>\n\n\n\n<p><strong>For reviewers<\/strong> &#8211; check out and test the branch locally before approving:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git fetch origin\ngit checkout feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>Run the test suite and verify the changes work as described in the PR. Leave constructive comments on specific lines in the PR interface.<\/p>\n\n\n\n<p><strong>For authors<\/strong> &#8211; respond to review comments by making additional commits on the same branch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git add src\/auth\/login.py\ngit commit -m \"Address review: add input validation to login endpoint\"\ngit push<\/code><\/pre>\n\n\n\n<p>The PR updates automatically with the new commits. Most teams require at least one approval before merging. Branch protection rules on GitHub and GitLab let you enforce this &#8211; along with requirements like passing CI checks, no merge conflicts, and signed commits.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Merge the Feature Branch<\/h2>\n\n\n\n<p>After approval, it is time to merge the feature branch into main. Git offers three main merge strategies, each with different trade-offs for your commit history.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Merge Commit (Default)<\/h3>\n\n\n\n<p>Creates a merge commit that preserves the full branch history. All individual commits from the feature branch appear in main along with the merge commit itself.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout main\ngit merge feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>Best for: teams that want a complete audit trail of every commit on every branch.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rebase and Merge<\/h3>\n\n\n\n<p>Replays each feature branch commit on top of main, creating a linear history with no merge commits. This produces the cleanest <code>git log<\/code> output.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout feature\/add-user-authentication\ngit rebase main\ngit checkout main\ngit merge feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>Best for: teams that prefer a clean, linear commit history. Avoid rebasing branches that others are actively working on &#8211; it rewrites commit hashes and causes conflicts for collaborators.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Squash and Merge<\/h3>\n\n\n\n<p>Combines all feature branch commits into a single commit on main. The branch history is collapsed into one clean commit.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout main\ngit merge --squash feature\/add-user-authentication\ngit commit -m \"Add user authentication with JWT (#42)\"<\/code><\/pre>\n\n\n\n<p>Best for: teams that want each feature represented as a single commit on main. Works well when feature branches have messy &#8220;WIP&#8221; commits that do not add value to the main branch history.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Delete Merged Branches<\/h2>\n\n\n\n<p>Once a feature branch is merged, delete it to keep your repository clean. Stale branches accumulate fast and make it hard to find active work.<\/p>\n\n\n\n<p>Delete the local branch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git branch -d feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>The <code>-d<\/code> flag only deletes the branch if it has been fully merged. Use <code>-D<\/code> to force-delete an unmerged branch (use with caution).<\/p>\n\n\n\n<p>Delete the remote branch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git push origin --delete feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>To clean up stale remote tracking references on your local machine:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git fetch --prune<\/code><\/pre>\n\n\n\n<p>Most hosting platforms (GitHub, GitLab) have an option to automatically delete branches after merge. Enable it in your repository settings to reduce manual cleanup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 8: Handle Merge Conflicts<\/h2>\n\n\n\n<p>Merge conflicts happen when two branches modify the same lines in the same file. Git cannot automatically decide which version to keep, so you resolve it manually. This is a normal part of working with feature branches.<\/p>\n\n\n\n<p>When a merge or rebase hits a conflict, Git marks the affected files. Check which files need attention:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git status<\/code><\/pre>\n\n\n\n<p>Files with conflicts appear under &#8220;Unmerged paths.&#8221; Open each conflicted file and look for the conflict markers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD\ndef authenticate(token):\n    return verify_jwt(token, secret=settings.JWT_SECRET)\n=======\ndef authenticate(token):\n    return verify_jwt(token, algorithm=\"HS256\")\n&gt;&gt;&gt;&gt;&gt;&gt;&gt; feature\/add-user-authentication<\/code><\/pre>\n\n\n\n<p>The section between <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD<\/code> and <code>=======<\/code> is the main branch version. The section between <code>=======<\/code> and <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;<\/code> is the feature branch version. Edit the file to keep the correct code and remove the conflict markers.<\/p>\n\n\n\n<p>After resolving all conflicts, stage the files and complete the merge:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git add src\/auth\/login.py\ngit commit -m \"Resolve merge conflict in authentication function\"<\/code><\/pre>\n\n\n\n<p><strong>Reducing conflict frequency<\/strong> &#8211; regularly pull updates from main into your feature branch to stay in sync:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git checkout feature\/add-user-authentication\ngit merge main<\/code><\/pre>\n\n\n\n<p>This catches conflicts early when they are small, rather than discovering a massive conflict at merge time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 9: Git Flow vs GitHub Flow vs Trunk-Based Development<\/h2>\n\n\n\n<p>Feature branches are used in every major Git workflow, but the rules around them differ. Choosing the right workflow depends on your team size, release cadence, and deployment process.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Git Flow<\/h3>\n\n\n\n<p>Uses long-lived branches: <code>main<\/code>, <code>develop<\/code>, <code>feature\/*<\/code>, <code>release\/*<\/code>, and <code>hotfix\/*<\/code>. Features branch off <code>develop<\/code>, not <code>main<\/code>. Releases get their own branch for stabilization. Good for software with versioned releases (desktop apps, libraries). Overkill for web apps with continuous deployment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">GitHub Flow<\/h3>\n\n\n\n<p>Simpler model with just <code>main<\/code> and feature branches. Every feature branch merges directly into <code>main<\/code> via a PR. Main is always deployable. Good for web apps and services with continuous deployment. Most teams find this workflow strikes the right balance between simplicity and safety.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Trunk-Based Development<\/h3>\n\n\n\n<p>Developers commit directly to main (the &#8220;trunk&#8221;) in small, frequent increments. Feature branches exist but are extremely short-lived &#8211; usually merged within hours, not days. Feature flags control whether incomplete code is active in production. Demands strong CI\/CD, automated testing, and disciplined team practices. Used by Google, Meta, and other large engineering organizations. If your team follows <a href=\"https:\/\/computingforgeeks.com\/gitops-best-practices-for-serverless-projects\/\" target=\"_blank\" rel=\"noreferrer noopener\">GitOps practices<\/a>, trunk-based development pairs naturally with automated deployment pipelines.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Git Branch Command Reference<\/h2>\n\n\n\n<p>This table covers the most common Git commands for working with feature branches. Keep it handy as a quick reference.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Command<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>git branch<\/code><\/td><td>List local branches<\/td><\/tr><tr><td><code>git branch -a<\/code><\/td><td>List local and remote branches<\/td><\/tr><tr><td><code>git checkout -b branch-name<\/code><\/td><td>Create and switch to a new branch<\/td><\/tr><tr><td><code>git switch -c branch-name<\/code><\/td><td>Create and switch (modern syntax, Git 2.23+)<\/td><\/tr><tr><td><code>git checkout branch-name<\/code><\/td><td>Switch to an existing branch<\/td><\/tr><tr><td><code>git push -u origin branch-name<\/code><\/td><td>Push branch and set upstream tracking<\/td><\/tr><tr><td><code>git merge branch-name<\/code><\/td><td>Merge branch into current branch<\/td><\/tr><tr><td><code>git merge --squash branch-name<\/code><\/td><td>Squash all commits into one before merging<\/td><\/tr><tr><td><code>git rebase main<\/code><\/td><td>Rebase current branch onto main<\/td><\/tr><tr><td><code>git branch -d branch-name<\/code><\/td><td>Delete merged local branch<\/td><\/tr><tr><td><code>git branch -D branch-name<\/code><\/td><td>Force-delete local branch (even if unmerged)<\/td><\/tr><tr><td><code>git push origin --delete branch-name<\/code><\/td><td>Delete remote branch<\/td><\/tr><tr><td><code>git fetch --prune<\/code><\/td><td>Remove stale remote tracking references<\/td><\/tr><tr><td><code>git log --oneline main..HEAD<\/code><\/td><td>Show commits on current branch not in main<\/td><\/tr><tr><td><code>git stash<\/code><\/td><td>Temporarily save uncommitted changes<\/td><\/tr><tr><td><code>git stash pop<\/code><\/td><td>Restore stashed changes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Feature branches keep your main branch stable while giving developers freedom to build, experiment, and iterate. The workflow is the same regardless of platform &#8211; create a branch, commit your work, push, open a PR, get it reviewed, and merge. For production environments, combine branch protection rules with automated CI\/CD to ensure nothing hits main without passing tests and peer review.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Feature branches are the backbone of collaborative Git workflows. They let you develop new functionality, fix bugs, or experiment &#8211; all without touching the main branch. Every change stays isolated until it is reviewed, tested, and merged. This guide covers the full feature branch workflow from creation to merge and cleanup. Whether your team follows &#8230; <a title=\"Git Feature Branch Workflow &#8211; Develop Without Affecting Main\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/implement-new-feature-in-git-without-affecting-master-branch\/\" aria-label=\"Read more about Git Feature Branch Workflow &#8211; Develop Without Affecting Main\">Read more<\/a><\/p>\n","protected":false},"author":16,"featured_media":71559,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[299,50,68],"tags":[533],"class_list":["post-71496","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to","category-linux-tutorials","category-programming","tag-git"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/71496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=71496"}],"version-history":[{"count":1,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/71496\/revisions"}],"predecessor-version":[{"id":163599,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/71496\/revisions\/163599"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/71559"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=71496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=71496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=71496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}