0

I have branch A with a few commits I need to cherry-pick into branch B. In the first cherry-picks I've added code that I've later removed in the last commits.

When I try to cherry pick them using first_commit^..last_commit it still cherry-picks the commits one by one - forcing me to solve conflicts between the code I added in the first commits and other developers code, even though I don't really need to solve these conflicts- as I've deleted this code in the last commits I'm trying to cherry-pick anyway!

So my question is: is there a way to cherry-pick a range of commits without going through them one by one (solving conflicts for each one of them)- but only the end result of their changes in code (solving conflicts, if any, between the changes after all the commits were applied and the rest of the code).

P.S. I cannot pull A into B as it contains other content I don't want, and I think I've also tried rebasing with similar results..

Thanks!

elad
  • 13
  • 1
  • 3
  • 4
    "*We have a script that depends on the commits' hash, so it's better if the solution actually cherry-picks the commits and not only their content.*" ... but the new commit produced by cherry-pick will **not** have the same hash. – Romain Valeri May 12 '22 at 10:27
  • @RomainValeri you're right, forget about that part – elad May 12 '22 at 10:38

1 Answers1

3

One quick way can be : instead of cherry-picking a sequence of individual commits you can create one single squashed commit using git merge --squash.


If you want to have a sequence of commits in the end result, then you will need to use cherry-pick or rebase to replay individual commits, and you may have to solve conflicts on a per commit basis.

You can try to avoid cherry-picking the problematic commits :

if your starting history looks like this :

*--*--*--*--*--*--*--*--*--* <- main
    \
     \
      x1--a--b--c--d--e--x2 <- feature
      ^                  ^
  problematic commit     |
                     revert of commit x1

you can try to run git cherry-pick x1..e (all commits up to e, excluding x1) instead of git cherry-pick main..feature (all commits up to feature excluding main, but including x1 and x2)


[update] from your comment, it looks like you want to edit your history (e.g: split some existing commits into "parts you want to keep" vs "parts you want to discard"). There are several ways to do that :

if you can afford to squash all your devs in one single commit, here is one way :

  • form your branch, create a temporary branch :
git checkout -b wip
  • to squash your commits together, spot the <sha> of the commit where your branch forked from master branch, and use git reset --soft :
git reset --soft <sha>
git commit -m "my devs in one single commit"
  • now repeat several time : inspect the diff with previous commit, remove a piece of code from your commit
git diff HEAD^ HEAD
# edit a file
git add file
git commit --amend

Once you have a result which contains only what you want to port, you can rebase or merge with target branch

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • Thanks @LeGEC ! Regarding 'git merge --squash' Can you clarify how should I do it if as I've stated in the original post I cannot pull/merge A into B as it contains other content I don't want? I guess this is what I'm looking for? https://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git – elad May 15 '22 at 08:30
  • Regarding the second approach I can't always do that since I might need a part of a commit.. That's why I can't just exclude it from my cherry-picking, but I need the end-result of all the commits.. – elad May 15 '22 at 08:33