Search code examples
gitversion-controlgit-mergegit-rebase

Applying Git commits from one branch to another completely unrelated branch


So I am relatively new to Git and I am struggling with some of the concepts and which ones I should apply in order to achieve my desired target state. I am also using Visual Studio Code for the development with the Git Source Control extension.

The source code (Marlin firmware) I am working on is available for download online but requires a number of tweaks specific to my application. I started out by downloading their v2.1.2.1 code from Github and then created a local repo and branch in Visual Studio Code. I decided to call my local branch 'master-2.1.2.1'. I then created a new branch from 'master-2.1.2.1' called 'DEBUG-2.1.2.1' where I then made a number of commits specific to my needs. Once I had a working DEBUG version, I then created a new branch from 'DEBUG-2.1.2.1' called 'V1-2.1.2.1'. I then switched to 'V1-2.1.2.1' and made another load of commits specific to tweaks I needed to make for my needs.

I then pushed my local repo and branches to my own Github account for backup purposes.

Then Marlin v2.1.2.2 was released. I downloaded the source code for v2.1.2.2 from Github and created a new local branch (unrelated to any of my prior branches) called 'master-2.1.2.2' and checked in all of the new source code for v2.1.2.2 into that new branch. I then created a new local branch from 'master-2.1.2.2' called 'WIP-2.1.2.2' Now I am trying to work out how do I apply all my specific tweaks/commits in an intelligent way from 'v1-2.1.2.1' into 'v1-2.1.2.2' without having to try and remember all of the very specific changes I made while working on v2.1.2.1.

I cannot figure out if this is the perfect use case for Git rebase. Remember that in my repo - branch 'V1-2.1.2.1' and 'V1-2.1.2.2' are unrelated. They are in essence two completely unrelated branches.

To help clarify things, let me try and illustrate it as follows:

BRANCH #1 FLOW ----> 'master-2.1.2.1' -> 'DEBUG-2.1.2.1' -> 'v1-2.1.2.1' BRANCH #2 FLOW ----> 'master-2.1.2.2' -> 'v1-2.1.2.2' -> [Apply all commits from (unrelated) BRANCH #1 FLOW] -> to create my specifically tweaked 'v1-2.1.2.2'.

I hope the above makes sense. Should I be going about this a different way?

I tried using Git cherry pick and Git rebase from within Visual Studio Code and it didn't seem to work as I intended. When I looked at a source code file from within the 'V1-2.1.2.2' source tree I expected to see my specific tweaks applied but no changes were applied so maybe I did something wrong or maybe I am not using it right or maybe I need to do it via the command line or maybe there is a bug with the Git Source Code extension available for install from the Visual Studio Code marketplace.

I am happy to do 3-way interactive merging for each commit just to make sure the latest of my specific tweaks from each of my commits is applied to the 'V1-2.1.2.2' source tree but I am struggling to see how to do that correctly. And then I got lost in a Google and YouTube rabbit hole which is why I thought it would be best to come here and ask the Stack Overflow community what I should do specific to my use case.

Any help would be greatly appreciated!

Thanks, Martin


Solution

  • So.... to your point: the fact that the branches are not related in your repo is something that git does not care about if you will do a rebase.

    So, I assume that the first commit that you did in master-2.1.2.1 is the code as is from the upstream for version 2.1.2.1 and the first commit in branch master-2.1.2.2 is the code of 2.1.2.2 from upstream.... then, the first commit in master-2.1.2.1 will be called X (use the commit ID for that first commit)..... so.... you can do this:

    git branch -f WIP-2.1.2.2 V1-2.1.2.1 # place the WIP on top of the branch that has all the stuff we want to rebase
    git rebase X WIP-2.1.2.2 --onto master-2.1.2.2
    

    If you feel like you really want to take a look at each commit, then use -i (interactive) when running the rebase as an additional option and when the commits are listed, switch pick for edit in all commits.... save and exit and git will stop right after applying each commit that it is rebasing.... you can do any adjustments and you will need to do git add .; git commit --amend --no-edit to apply those new changes you introduce live. When each commit is ready to move to the next you do: git rebase --continue and git will move to the next commit.

    After rebasing is finally done (interactive or not), you will end up with WIP-2.1.2.2 having all the tweaks you did in V1-2.1.2.1 past the original commit X but applied on top of master-2.1.2.2.

    Having solved the question in point, I wanna ask why you started a new repo from scratch. You should have cloned (even locally) the upstreasm repo and create your branches from the upstream branches or tags.