Applying a diff file using patch(1)
fails in case that the diff file
introduces new directories. This situation can happen, for example, when you
work in a git repository as I do, commit a subdirectory with some files in it,
then squash all your commits into a single commit using git rebase -i
and
finally create a diff file using git format-patch
.
In my case, I had to apply my work done in a git repository on top of a
subversion branch. During the development, I added tons of test fixtures in a
fixtures/
directory. But when applying the final patch on top of the
subversion branch, my test fixtures all ended up in the root directory,
overwriting each other, as that’s what patch(1)
does when it comes across a
non-existing directory.
Solution
Assuming your diff file is called 0001-Your-Changes.patch
, the following Ruby
script will scan your diff file and create all neccessary directories:
ruby -n -E utf-8 -r fileutils \
-e 'FileUtils.mkdir_p(File.dirname($1.split("/")[1..].join("/"))) if $_ =~ /^[+][+][+]\s(.*)$/' \
< 0001-Your-Changes.patch
Then proceed by running patch -p1 < 0001-Your-Changes.patch
as usual.
Check the -n
command line option of ruby(1)
, which behaves similar to sed
and awk
.