0

I have the following situation:

two branches were created from master at different times

    T0                T1
----+-----------------+------> master
    |                 |
    |                 |
    +---- BranchA     +---- BranchB

Development occurred on BranchA after time T0

Some, but not all of those commits were merged in master after time T0, but before time T1

I would like to now cherry-pick all the commits in BranchA that do not exist in BranchB into BranchB

  • Does this answer your question? [How to cherry-pick a range of commits and merge them into another branch?](https://stackoverflow.com/questions/1994463/how-to-cherry-pick-a-range-of-commits-and-merge-them-into-another-branch) – Andrew McClement Feb 16 '22 at 23:54
  • How were *some* of the commits in branchA merged? You merge a whole branch. – Schwern Feb 17 '22 at 00:00
  • @Schwern they were commits made on BranchA as part of the normal dev process, then later on some were cherry-picked to the master before BranchB was created. – Shari Menson Feb 17 '22 at 00:54
  • While the mechanism behind `git cherry-pick` is a form of merge, the *result* of a cherry pick *isn't* a merge. This is probably the source of all your woes. Basically, someone planted a time bomb (or many small time bombs). They have now gone off. There is no simple solution, just a lot of hard clean-up work. – torek Feb 17 '22 at 03:31
  • @torek can you please clarify the term time bomb, is that related to git merging? – Shari Menson Feb 17 '22 at 07:50
  • It's related to the *lack* of merging: by cherry-picking specific commits, whoever did that action made doing a *future merge* very difficult. That's the "time bomb", it goes off when the future person-who-wants-to-merge tries to merge. – torek Feb 18 '22 at 03:58

2 Answers2

0

Untested, but

git switch BranchB # Use git checkout BranchB if you prefer.
git cherry-pick ..BranchA

should work. Taken from the examples section of https://git-scm.com/docs/git-cherry-pick.

Andrew McClement
  • 1,171
  • 5
  • 14
  • I did try that, the problem is it does all commits not the missing ones which means dealing with a whole bunch of cherry-pick conflicts. – Shari Menson Feb 16 '22 at 23:56
  • It should cherry pick precisely the commits which are ancestors of BranchA but not of HEAD (which will be BranchB). :( Not sure what to suggest. – Andrew McClement Feb 17 '22 at 00:03
0

Instead of cherry picking, rebase.

First, rebase branchA onto master.

This brings branchA up to date. No question of what parts of branchA are in master. No question whether they're compatible with master.

This will greatly simplify the process and give you an opportunity to resolve any conflicts between branchA and master without also involving branchB.

It's probably also a good idea to rebase branchB onto master just to make sure both branches are up to date and are working from a common base.

Then rebase branchB onto branchA. Or vice versa. Or cherry pick master..branchA (all the commits on branchA which are not in master) onto branchB.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • Correct me if I'm wrong but we should only rebase to the commit on master from which BranchB was created - correct? otherwise we'd get commits on master post BranchB being created - which is not what we want. – Shari Menson Feb 17 '22 at 00:50
  • @ShariMenson `git checkout branchA; git rebase master` Now branchA is only the commits which are not in master. Then `git checkout branchB; git cherry-pick master..branchA`. That will only pick [the commits in branchA which are not in master](https://git-scm.com/docs/gitrevisions#Documentation/gitrevisions.txt-Theememtwo-dotRangeNotation). – Schwern Feb 17 '22 at 02:44
  • just want to confirm this process will not include commits on master after T1 ? – Shari Menson Feb 17 '22 at 06:06
  • @ShariMenson Check the commits with `git log master..branchA`. You can also make a new branch off branchB to test with. – Schwern Feb 17 '22 at 09:23