optimus prime
optimus prime

Reputation: 774

How to cherry-pick changes from one file to another file?

I have two files called vvn.c and aqu.c I did changes to vvn.c and I have that commit in my git. How to cherry-pick the same changes to aqu.c The only difference is the API's.

vvn.c contains API's as vvn_function_names()

whereas aqu.c contains API's as unions_function_names()

I don't know how to do that. I know about cherry-picking into the same file. Is there any way to do that?

Upvotes: 12

Views: 8814

Answers (4)

ChuckEng
ChuckEng

Reputation: 11

I use a patch file. This way I can edit the paths in the patch file to match the new location(s).

You can create a patch file with:

git format-patch {commit}~1...{commit}

This generates a .patch file in the local directory with the changes.

-or-

git show {commit} > {my-changes.patch}

Where {my-changes.patch} is a filename/path you determine.

Now edit the {my-changes.patch} file in an editor and replace old paths with new paths. Other edits or changes can be made at this time.

Now you can apply the patch with:

git am < {my-changes.patch}

If you edited something and broke the patch, you will get an error. Check the steps and edits you may and try again. One nice thing about this method is that you can just reset, undo portions of an edit, or entire files in the edit if you like. But, the changes being applies are free of user typos, since git is doing the merge from the original changes.

It is important that before you commit the changes, diff the changes you have made and make sure they are what you want. Only then stage and commit them.

Note: git am has a bunch of options, like --ignore-whitespace and --interactive that can help you.

Upvotes: 1

We Are All Monica
We Are All Monica

Reputation: 13336

Another option that more easily preserves the author info of the original commit:

  • git cherry-pick normally
  • git mv the files into place
  • git commit --amend to modify the cherry-picked commit

If the commit in its original form would modify files that already exist in the repository, then you probably need a couple of extra steps (I haven't tested this part):

  • git checkout --orphan temp/cherry-pick (ref)
  • git reset
  • Follow the first set of steps to apply the commit
  • Finally switch back to the original branch and git cherry-pick temp/cherry-pick

Upvotes: 1

kan
kan

Reputation: 28951

Basically you need to make a diff on the vvn.c changes and apply them to a aqu.c. See e.g. here: How to apply a Git patch to a file with a different name and path?

However, this is quite tricky thing. Why do you have different file names which anyhow similar so that you should make same changes?

Probably it is better to come up with some another approach. E.g. for a C you could use #include and extract common part into a separate file.

Upvotes: 4

Tomas Kulich
Tomas Kulich

Reputation: 15628

Not exactly cherry-pick, but you might want to use:

git checkout <branch or sha of commit> -- filename

This checkouts the file by its version in another branch; it is the easiest possible solution, if it satisfy your needs (i.e., if you don't need to actually merge changes to the file from two separate branches)

The other possibility is to generate diff (you can generate diff from a range of commits just and limit it to one file) and then apply the diff. Check out: How to diff the same file between two different commits on the same branch?

Upvotes: 11

Related Questions