Cherry picking changes to specific files from a range of commits

681 views Asked by At

I have a branch into which I accidentally merged other peoples changes a long time ago, and now hundreds of files show up on a pull request that are not mine.

I would like to create a separate branch into which I would like to cherry-pick changes to my own files over those several dozen commits, so that my new pull request only contains my changes.

I found out how to cherry pick commits, and how to cherry pick files from one specific commit, but how do I cherry pick several files from a range of commits?

Is there perhaps a simpler solution?

2

There are 2 answers

0
Jeff Bowman On

If there is a single commit that you used to merge in, that you can avoid, then use git rebase to skip the merging commit.

-----origin/foo-------A----------------------------B----C----D
                      (where you merged in)        (commits on top of that)

  AFTER REBASE

-----origin/foo-------B'----C'----D'
                      (your commits, skipping A)

If instead your changes (B, C, and D above) actually touch the files you're trying to avoid, you'll need to use git filter-branch to rewrite those commits and avoid changing those files. Using the --tree-filter command, you can reset the part of each tree that you don't want to touch.

0
David Deutsch On

So if I understand you correctly, what you want to do first is cherry pick the range, i.e. git cherry-pick --no-commit. Then, remove the changes to your index with git reset. Then git add all of the files you want to commit, git commit those files, and finally git checkout . to get rid of the other local changes. This will result in a single, flattened commit that contains your changes.

Now, if instead what you want to do is include just those commits that have touched a particular set of files, you may want to take a look at an example given towards the bottom of this page that uses git rev-list to feed a list of all commits that have touched a particular filespec to cherry-pick. So if, for example, all your files were in mydir, something like git rev-list --reverse master -- mydir | git cherry-pick --stdin should do it.