What is the point of the different ingestion methods?

I just wrote this bug about add-path and add-file returning different hashes for regular files, and at the very end, I noticed that the only difference between the two is the FileIngestionMethod that they’re using:

add-file uses FileIngestionMethod::Flat, add-path uses FileIngestionMethod::Recursive, but there’s also TextIngestionMethod, which is just a monostate struct, and the comment on that also refers to a FileIngestionMethod::Fixed, which doesn’t seem to exist anymore.

I’m a little confused here. I understand that Recursive is needed to allow directories to be serialized, but what is the point of allowing the Recursive strategy on a flat file?

What is the TextIngestion strategy, and why is it needed? The comments mention that it forbids self-references and attaching a hash to the output, but if something is in a NAR archive, it is already fixed text.

I’m also confused about the prefixes ``, :r and :text. It seems that they don’t actually show up in NAR files, at least from what I could gather by prodding around with nix-store --dump and nix nar dump-path.

I’m also wondering if there’s a formal specification of the NAR format. There are hints here and there in the docs for nix-store --dump and nix nar dump-path, but nothing concrete.

1 Like

Recursive allows an executable bit set on the file. At least that’s an advantage that I’ve ran into; maybe there’s somethin else, too.

In particular, you can do fetchurl { executable = true; ... }

I think you’re aware, but the “flat” method is needed in order to get the same plain hash as everyone else (e.g. using sha256sum).