Given two directories, one a Git repository and the other not, how do you apply the recursive diff between those two directories as a patch to the Git repository?
This might happen if you download source code without its history and make changes to it, then later acquire the history and wanting to secure your changes.
... is to convert the non-repository into a Git repository before introducing
the change. The change can then be turned into a patch with git format-patch [--binary]
and applied with git apply
or git am
.
If you didn't think to do this it gets considerably more tricky.
... requires creating a recursive patch with something like diff
and applying
it with patch
or, preferably, git apply
. In many situations this actually
isn't difficult at all, it's just that there are a few edge-cases to look out
for:
- You have to tell
diff
to produce the unified diff format thatgit apply
needs. - If your changes span subdirectories you have to tell
diff
to operate recursively. - If you do operate recursively you have to tell
diff
to ignore the.git
folder in the destination repository to avoid corrupting it. - If you created any new files you need to explicitly tell
diff
to include them. - If there are any binary files you'll have trouble:
diff
only works with text, and the typical recommendation for binary diffs,bzdiff
, doesn't solve any other problemdiff
solves. The safe approach is to resolve these manually but for platform independent binary files, such as images and PDFs, you can probably get away with instructingdiff
to treat them as text files; I've tried this successfully but I don't guarantee the result. - As with normal
patch
operation you need to strip a file name prefix when applying.
The final invocation, executed from within the destination repository, looks like this:
diff --exclude=.git --recursive --unified --new-file --text ../non-repo |
git apply -p3
I can't remember if it's
-p2
or-p3
.