In branch egg
, file A
:
Value = A
is changed to
Value = B
In branch orange
:
$ git mv ./A ./B
Branch egg
is left as a branch for many weeks. Branch orange
is merged into the trunk. egg
is now so hopelessly out of date there's no reasonable path forward to rebasing or merging, but we can still steal at least some of that work back to save time.
Normally, one could do that with:
$ git checkout origin/egg <filename> -p
This is super convenient, because you can patch/edit all the chunks into the current branch -- you lose some git history but this usually is not as important as getting the work done.
However, with the rename above the patch will fail.
Is there a git command that is able to tell git "Please create a patch by pretending file A
in egg
is actually file B
that exists in the trunk". Bonus points for being able to use -p
to apply it, but I'm willing to give that up for any solution.
This comes up a lot when combining work performed in parallel. This example is heavily simplified, but in real cases I might have many more complex patches to apply involving hundreds of changes across maybe two or three renamed files. For small stuff this isn't bad, but for the kinds of changes above it's a lot of manual effort to carry over changes.
CodePudding user response:
Is there a git command that is able to tell git "Please create a patch by pretending file
A
inegg
is actually fileB
that exists in the trunk".
No.
Git will find renames on its own in some cases, when git diff
has rename-finding enabled. But there's no way to forcibly tell Git that a file is to be considered "renamed". Presumably you're hitting this case, otherwise cherry-pick would be working for you.
If you use git format-patch
to turn a commit into a patch file, you can manually edit the patch to claim a different file name. You could write your own program to do this too, but to achieve your ultimate goal (of being able to use git apply -p
) you'd probably be better off writing your program to:
- make a new, temporary branch from the base commit (parent of the
egg
-branch commit that you want to copy); - rename the file there and commit;
- cherry-pick the desired
egg
-branch commit into the new branch: Git will detect the rename and since the file's content still matches, will also complete the cherry-pick automatically - use the new commit-pair to make a patch that you can feed to
git apply
, or pause here to rungit checkout -p
with the new commit at the tip of the temporary branch; - delete the temporary branch.
(It's probably useful to make steps 1 and 5 separable so that you can do this over a range of commits.)
CodePudding user response:
For an individual file, you can also use the standard patch
command :
git diff master...egg -- A > /tmp/A.patch
patch B A.patch