Fetchpatch options masked by SHA256 sum

I was fixing a package by downloading a patch from Github via fetchpatch. After entering the sha256-sum, the patch would not apply cleanly and required some more changes with various fetchpatch-options (stripLen, extraPrefix). However, the patch would keep failing to apply and after a bit, I noticed that the patch applied never changed.

Apparently, the sha256-sum entered there is for the final patch after filterdiff has been running. And when Nix finds a pre-built patch that matches this sha256-sum, it will just take it. Hence, it looked like my changes to the derivation would do nothing.

Essentially, changing patch options now requires two builds all the time. First change the sha256-sum to something invalid, then update the fetchpatch options, build, see the actual sha256, insert this sha256 into the derivation, do another build. And if you forget the first step, your changed fetchpatch options will just be ignored.

Is there a way of working that prevents this issue? It seems like a bit of a developer trap to me.

Yeah, that is fixed-output derivations for you. It is even mentioned in the patches section of the manual.

At some point you need to accept the hash as given, otherwise you would need to keep re-downloading all sources and checking them.

There are two possible solutions that come to mind:

  • include all important arguments in the name of the derivation produced by fetchpatch (even a small hash might help)
  • split fetchpatch into two derivations – the determinization would remain fixed-output and then its output would be modified by another derivation based on the other fetchpatch arguments

Unfortunately, neither of these is backwards compatible in addition to other drawbacks so we would need to introduce fetchpatch2.

So until we decide to go with that, I can only suggest staying vigilant in the presence of fixed-output derivations. In newer versions of Nix, you can set the hash to an empty string instead of just changing it to something invalid, which might be more convenient for you (though fetchpatch does not support it at the moment fetchpatch: allow empty hash by DavHau · Pull Request #122543 · NixOS/nixpkgs · GitHub).

2 Likes

Oh, I was looking in the sources directly for the options, so I missed the docs, mea culpa. Thanks for clearing this up. I was guessing something in that direction, but your explanation gave me a lot more insights.

I’d seems like any change that might cause hashes in the derivations to change is a big headache and probably warrants a new command to not break tons of derivations.

For faking the SHA’s, I’ve settled on lib.fakeSha256 which (so far) always seemed to work. I’ve had weird issues with empty hashes in several places.

It’s possible to use nix-prefetch-url -A foo.patches . Or rather, it would be possible if patches referred to the single patch instead of being a list (the command will refuse even singleton lists). It’s often easy to temporarily expose the patch in some attribute, but I’m not sure if it’s really better than providing some valid but non-existent hash. I suppose the command is mainly useful for (fixed-output) builds that are expensive, as you avoid performing them twice.

EDIT: oh, I didn’t realize the topic is two weeks old already.