The manual sections The patch phase and Patches ought to describe how to make a .patch
file.
All it says right now is
They must be in the format accepted by the $ patch command
and I'm not sure what that means.
It's a pretty standard unix program: https://en.wikipedia.org/wiki/Patch_%28Unix%29
We can put this or a similar link to the docs, possibly with a couple examples. The patch
program accepts multiple formats, pretty any commonly used patch/diff/...
Please, no. A link to Wikipedia never constitutes documentation.
Wikipedia says to do this:
diff -u oldFile newFile > mods.diff
So let's try that.
default.nix
{ stdenv }:
stdenv.mkDerivation {
name = "patch-demo";
src = ./.;
patches = [ ./demo.diff ];
}
foo.txt
two
three
Let's pretend foo.txt
is our source file, and we want demo.diff
to be a patch that changes two
to four
.
chris@cubby ~ ❯❯❯ cd (mktemp -d)
chris@cubby /t/tmp.VMXEEVjRVY ❯❯❯ cp ~/nix/pkgs/patch-demo/foo.txt oldFile
chris@cubby /t/tmp.VMXEEVjRVY ❯❯❯ echo -e "one\nfour\nthree\n" > newFile
chris@cubby /t/tmp.VMXEEVjRVY ❯❯❯ diff -u oldFile newFile > ~/nix/pkgs/patch-demo/demo.diff
So that creates a diff that looks like this:
demo.diff
--- oldFile 2017-11-17 15:19:40.014637150 -0500
+++ newFile 2017-11-17 15:20:09.628909087 -0500
@@ -1,3 +1,4 @@
one
-two
+four
three
+
So far so good, I made a patch file! But it looks like I did something wrong, because most of the patches in nixpkgs have a header that looks something like this
From 33b25c2e3c7a002c7f726cd79fc4bab22b1299be Mon Sep 17 00:00:00 2001
From: Thomas Tuegel <[email protected]>
Date: Tue, 27 Oct 2015 18:07:54 -0500
Subject: [PATCH] follow symlinks
---
src/appearancegtk2.cpp | 2 +-
src/iconthemesmodel.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
Mine doesn't and I don't know why it's different.
I'm not sure how it will know which file to apply the patch to. Indeed it doesn't work:
chris@cubby ~ ❯❯❯ nix install patch-demo
installing ‘patch-demo’
these derivations will be built:
/nix/store/5jvgpr4bq6ji04nxd4imgbsg2jv5di4q-patch-demo.drv
building path(s) ‘/nix/store/vrda5am5jl91bx8qmm8cg2g2j7s3662g-patch-demo’
unpacking sources
unpacking source archive /nix/store/1h5cgxhpban3bw4fsb2mr7flxr1zwa8w-patch-demo
source root is patch-demo
patching sources
applying patch /nix/store/3mgg0p8irr7z0g3ijwfr3l38kj3lb7da-demo.diff
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|--- oldFile 2017-11-17 15:19:40.014637150 -0500
|+++ newFile 2017-11-17 15:20:09.628909087 -0500
--------------------------
File to patch:
Skip this patch? [y]
Skipping patch.
1 out of 1 hunk ignored
builder for ‘/nix/store/5jvgpr4bq6ji04nxd4imgbsg2jv5di4q-patch-demo.drv’ failed with exit code 1
So I guess I need to edit the diff file to fix the file name?
demo.diff
--- foo.txt 2017-11-17 15:19:40.014637150 -0500
+++ foo.txt 2017-11-17 15:20:09.628909087 -0500
@@ -1,3 +1,4 @@
one
-two
+four
three
+
chris@cubby ~ ❯❯❯ nix install patch-demo
installing ‘patch-demo’
these derivations will be built:
/nix/store/i5ikqs1smf01lywr7jpi2q8s47zv9kcx-patch-demo.drv
building path(s) ‘/nix/store/rw1hi6qvnsmbaayxk12kfcrcmf2lr0fc-patch-demo’
unpacking sources
unpacking source archive /nix/store/ivynk2f4gwvnn503vqrcxn7xhp47cvfn-patch-demo
source root is patch-demo
patching sources
applying patch /nix/store/b6pfb9mh2yacj1dqz26g7qy6qfhp0pz1-demo.diff
can't find file to patch at input line 3
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|--- foo.txt 2017-11-17 15:19:40.014637150 -0500
|+++ foo.txt 2017-11-17 15:20:09.628909087 -0500
--------------------------
File to patch:
Skip this patch? [y]
Skipping patch.
1 out of 1 hunk ignored
builder for ‘/nix/store/i5ikqs1smf01lywr7jpi2q8s47zv9kcx-patch-demo.drv’ failed with exit code 1
error: build of ‘/nix/store/i5ikqs1smf01lywr7jpi2q8s47zv9kcx-patch-demo.drv’ failed
Nope, still doesn't work. Not sure why.
The patch header is optional. The problem with your patch is that by default file names are expected to be prefixed with one arbitrary directory, e.g. a/foo.txt
, not just foo.txt
.
I'd recommend this method of generating patches:
cd some-dir/with/files
git init
git add . # or "git add some-file" if there is a lot of files and directories here
edit some files
git diff > ../changes.patch
@orivej Thank you!
I submitted #31778 to add that to the manual.
I know this is a long time since, but there must be a better and easier way by now.
Making a patch for Firefox, and the initial git add .
, takes some time as one might imagine.
The firefox codebase is what, mercurial? I would suggest that instead. Or just making a copy before modifying the file and using diff -u a b
.
You can git add path1 path2 …
— only paths that you want to change.
Most helpful comment
Please, no. A link to Wikipedia never constitutes documentation.