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
diffto produce the unified diff format thatgit applyneeds. - If your changes span subdirectories you have to tell
diffto operate recursively. - If you do operate recursively you have to tell
diffto ignore the.gitfolder in the destination repository to avoid corrupting it. - If you created any new files you need to explicitly tell
diffto include them. - If there are any binary files you'll have trouble:
diffonly works with text, and the typical recommendation for binary diffs,bzdiff, doesn't solve any other problemdiffsolves. 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 instructingdiffto treat them as text files; I've tried this successfully but I don't guarantee the result. - As with normal
patchoperation 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 -p3I can't remember if it's
-p2or-p3.