Skip to content

Instantly share code, notes, and snippets.

@atima
Last active July 12, 2025 04:15
Show Gist options
  • Save atima/6e11a155fffa43f9184a775f69bf5ad7 to your computer and use it in GitHub Desktop.
Save atima/6e11a155fffa43f9184a775f69bf5ad7 to your computer and use it in GitHub Desktop.
Procedure to move only specific commits to a branch while maintaining linear history.

Moving and Realigning Commits

Sometimes you need to transfer specific changes from a feature branch (e.g., dev) to a stable branch (e.g., main) without bringing over all subsequent development. This often involves:

  • Cherry-picking selected commits from dev onto main.
  • Rebasing dev to "fast-forward" its base to the newly updated main branch, making dev appear to branch from a later point.

This method results in a clean, linear history on main, making it easier to track specific feature integrations.

Important Note: This workflow rewrites the history of the dev branch. If dev is a shared branch that other team members are actively working on, performing a rebase will cause significant headaches and potential data loss for them. Only use this strategy on private or unshared branches.

Goal:

Before                            After
A---B (main)                      A---B---C'---D' (main)
     \                                          \
      C---D---E (dev)                            E' (dev)

Step 1: Apply C and D to main

  1. Switch to the main branch:

    git checkout main
    
  2. Identify the commit hashes for C and D on the dev branch.

    Use git log dev to see the commit history of dev. Look for the commit messages corresponding to C and D and note down their full commit hashes. Let's assume:

    • Commit C hash: commit_C_hash
    • Commit D hash: commit_D_hash
  3. Cherry-pick C and D onto main:

    git cherry-pick commit_C_hash
    git cherry-pick commit_D_hash
    

    Now, the main branch will look like: A---B---C'---D'

    Before                            After
    A---B (main)                      A---B---C'---D' (main)
         \                                 \
          C---D---E (dev)                   C---D---E (dev)
    

Step 2: Make dev know it's branched from main at D

This is achieved by rebasing dev onto the new head of main (which is now D).

  1. Switch back to the dev branch:

    git checkout dev
    
  2. Identify the commit hashes for D' on the main branch.

  3. Rebase dev onto main:

    git rebase --onto commit_D'_hash commit_D_hash
    

    More on rebase --onto: https://womanonrails.com/git-rebase-onto

    Now, the goal is reached.

    Before                            After
    A---B---C'---D' (main)            A---B---C'---D' (main)
         \                                          \
          C---D---E (dev)                            E (dev)
    

Step 3: Push changes to remote repositories

❗Do not force push until you are sure about the result.

git push --force-with-lease dev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment