git: Apply changes introduced by commit in one repo to another repo

Git

Git Problem Overview


I have a repo1 and repo2 on local machine. They are very similar, but the latter is some kind of other branch (repo1 is not maintained anymore).

/path/to/repo1 $ git log HEAD~5..HEAD~4
<some_sha> Add: Introduce feature X

How to apply changes made by commit <some_sha> in repo1 to repo2?

Do I need to prepare some patch, or is it possible to do some cherry-pick between the repos?

How about doing the same but for range of commits?

Git Solutions


Solution 1 - Git

You probably want to use git format-patch and then git am to apply that patch to your repository.

/path/to/1 $ git format-patch sha1^..sha1
/path/to/1 $ cd /path/to/2
/path/to/2 $ git am -3 /path/to/1/0001-…-….patch

Or, in one line:

/path/to/2 $ git --git-dir=/path/to/1/.git format-patch --stdout sha1^..sha1 | git am -3

Solution 2 - Git

You can do cherry-pick if you add the second repo as a remote to the first (and then fetch).

Solution 3 - Git

As a hack, you can try modifying recipe for comparing commits in two different repositories on GitTips page, i.e.:

GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects \
git cherry-pick $(git --git-dir=../repo/.git rev-parse --verify <commit>)

where ../repo is path to the other repository.

With modern Git you can use multiple revisions and revision ranges with [cherry-pick][git-cherry-pick].

The $(git --git-dir=../repo/.git rev-parse --verify <commit>) is here to translate <commit> (for example HEAD, or v0.2, or master~2, which are values in the second repository you copy from) into SHA-1 identifier of commit. If you know SHA-1 of a change you want to pick, it is not necessary.

NOTE however that Git can skip copying objects from source repository, as it doesn't know that the alternate object repository is only temporary, for one operation. You might need to copy objects from the second repository with:

GIT_ALTERNATE_OBJECT_DIRECTORIES=../repo/.git/objects git repack -a -d -f

This puts those objects borrowed from second repository in original repository storage

Not tested.


A not so hacky solution is to follow knittl answer:

  • Go to second repository you want to copy commits from, and generate patches from commits you want with git format-patch
  • Optionally, copy patches (0001-* etc.) to your repository
  • Use git am --3way to apply patches

[git-cherry-pick]: https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html "git-cherry-pick(1) Manual Page - Apply the changes introduced by some existing commits"

Solution 4 - Git

I wrote a small script for applying the diff output of repo diff https://github.com/raghakh/android-dev-scripts/commit/a57dcba727d271bf2116f981392b0dcbb22734d0

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontakeshinView Question on Stackoverflow
Solution 1 - GitknittlView Answer on Stackoverflow
Solution 2 - GitwRARView Answer on Stackoverflow
Solution 3 - GitJakub NarębskiView Answer on Stackoverflow
Solution 4 - GitRaghaView Answer on Stackoverflow