Git: Apply a patch as if the changes were manually

100 views Asked by At

I have changes in a feature branch, that I'd like to transfer over to the develop branch commit-by-commit as if I initially created them on develop in the first place, by hand.

Constraints:

  • If necessary, I want to manually fix merge conflicts per commit.
  • The commits on develop should be completely independent of the feature branch. I.e. they should be new commits, not sharing any ID (or else(?)) with the feature branch.

What I tried

I tried to use format-patch and git am / git apply for that, but it fails at merging.

I created a patch file containing several patches using
git format-patch [COMMIT ID] --stdout > ~/my.patch

Applying the patch results in errors
$ git am --3way --ignore-whitespace ~/my.patch

Applying: commit message 1
Applying: commit message 2
Applying: commit message 3
Applying: commit message 4
Applying: commit message 5
Using index info to reconstruct a base tree...
M   app/myfile1.py
M   app/myfile2.py
M   tests/test_myfile1.py
error: patch failed: app/myfile1.py:61
error: app/myfile1.py: patch does not apply
error: patch failed: app/myfile3.py:58
error: app/myfile3.py: patch does not apply
error: Did you hand edit your patch?
It does not apply to blobs recorded in its index.
Patch failed at 0005 Review
hint: Use 'git am --show-current-patch=diff' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

(I did not touch the patch file after creation)

Trying to manually resolve conflicts says there is no conflict:
git mergetool

No files need merging

Notes

The following works fine in regard of merging/conflict solving, but it crushes all commits into one single commit:

git checkout feature
git diff [COMMIT ID] > ~/my.patch
git checkout develop
git apply --3way ~/my.patch```
2

There are 2 answers

3
eftshift0 On BEST ANSWER

If you want to reapply a series of commits that are already merged (and reverted) into the current branch, you need to trick git into thinking that the commits have never been merged in the first place... it's not that hard, really, just requires a little bit more work than usual. Let's say that it is a series of 4 commits one after the other, the last one being X.... then you could do this:

git checkout X~4 # go back to the commit _before_ the 4 commits we want to trick git into believing are brand new
git cherry-pick HEAD..X # reapply the 4 commits, no changes in them... but these are new commits to git
# let's bring them over to develop
git rebase --onto develop HEAD~4 HEAD

And you got your commits on top of develop

0
DarkTrick On

Based on eftshift0's answer:

Create a new branch with exactly the same commit content, but different commit IDs

Given the following situation: enter image description here

You could do the following:

git checkout feature
git checkout A1
git cherry-pick HEAD..B3
git checkout -b feature_new