Reputation: 8820
I want to move two files from one repository to another. The files were originally added as:
/src/init/Price.cs
/tests/init/PriceTests.cs
The two files were later renamed to:
/src/init/PriceValue.cs
/tests/init/PriceValueTests.cs
And then moved to:
/src/moved/PriceValue.cs
/tests/moved/PriceValueTests.cs
I've tried to go by this description to create a set of patches for these files, but I'm unsure how to pass in the six different paths the files have existed on.
I've managed to find all the commit IDs affecting PriceValue.cs
(across renames and moves), but passing those IDs to Git fails with the following error message:
$ git format-patch -o /tmp/pricevaluepatches $(git log --all dfeeb 6966b 9f882 …)
-bash: /usr/local/bin/git: Argument list too long
So, how do I create a set of patches for this that only contains the changes to the mentioned files, but contains it across one rename and one move of each file?
Upvotes: 8
Views: 847
Reputation: 865
To achieve the goal from the question via a merge (instead of individual patch moving via format-patch as the question asked) one can remove all other files in a new commit and then merge that commit across repositories into the target repository (adapted from https://stackoverflow.com/a/10548919/7496656 ):
cd path/to/project-a
git checkout -b for-b master # or whichever branch you want to merge from
git rm -r .
git checkout HEAD -- src/moved/PriceValue.cs tests/moved/PriceValueTests.cs
git commit
cd path/to/project-b
git remote add project-a path/to/project-a
git fetch project-a
git merge --allow-unrelated-histories project-a/for-b
git remote remove project-a
cd path/to/project-a
git branch -D for-b
This has the advantage that all the history is there, the commit IDs stay the same and there is no need to juggle individual commits nor find them. This may have the disadvantage that a linearised view (like git log
) as opposed to the graph view (like gitk
) probably becomes more confusing as the number of unrelated commits gets greater.
One could additionally filter repository project-a
before the merge, to hide unrelated files or commits. However the downside of that are: If you do this across a repository merge more than once, possibly also in the other direction, it makes the history less clean as the common history only occurs multiple times (once for each merge). This would also make this solution more difficult than your initially tried one. This would also have the downside that the commit IDs don't stay the same and thus it would not be as easy to find which were the same commit across repositories.
Upvotes: 1
Reputation: 36859
You can get the patches of a few specific files but not earlier than commit sha1
using
git format-patch sha1 -- file1 file2 ...
Any of the files can be an old file (prior to a rename) or an existing file.
If you want all commits until commit sha1
you can use
git format-patch --root sha1 -- file1 file2 ...
So in your case, all commits until now (HEAD
) of your six files:
git format-patch --root HEAD -- /src/init/Price.cs /src/init/PriceValue.cs /src/moved/PriceValue.cs /src/init/PriceTests.cs /src/init/PriceValueTests.cs /src/moved/PriceValueTests.cs
Upvotes: 6
Reputation: 30327
Hmm..... Assuming I want to keep the patch files the way they are, what I would do is get the patch file applied on a branch so that I can then cherry-pick it on the right branch.
So, suppose I have on my master branch a file named /tests/moved/PriceValueTests.cs and I want to apply on it a patch that has the name /tests/init/PriceTests.cs instead. Assuming I don't want to hack the patch file, what I would do is:
This is so that git can track the name change and be able to apply it successfully. I've done it a number of times and git's file rename algorithm tends to get it right.
Upvotes: 1