NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
11.5k stars 1.44k forks source link

`nix build --from-index` #5078

Open johnrichardrinehart opened 2 years ago

johnrichardrinehart commented 2 years ago

Problem Decsription

Sometimes my workflow gets messy and I have unrelated changes in my worktree. So, I git add -p and stage the (ostensibly) proper change set. But, wait - will these committed changes even build? I only know if changeset(A+B) builds - not if changeset(A)+changeset(B) builds. Well, I guess I can

$ git stash push --keep-index && nix build

to check for failures. Okay, that failed. Let's

$ git stash pop

and then

$ git add -p $HOPEFULLY_RELEVANT_FILES

and stash and build again.

..... Nope, still not working.... Agh, nix build knows if I haven't added untracked files that are needed. Why can't it just ignore unstaged changes and build only using the history+staged changes using something like

Proposed User Interface

nix build --from-index <...>

Would such a feature be supported if a PR is provided?

Kha commented 2 years ago

But, wait - will these committed changes even build?

If you commit them first, you can then use something like nix build .\?ref=HEAD to build the commit (and only it), and afterwards amend from the working area if necessary. But your proposed flag would also be nice to have.

dramforever commented 2 years ago

This should probably be a parameter to git+file: instead of a flag

johnrichardrinehart commented 2 years ago

@dramforever I'm not familiar with git+file:, I'll do some research, now. Can you give me an example invocation/docs?

And, frankly, I think this is usefully enough to be a flag. I'm not sure how many people are using git+file: but it's not something I would think to reach for. My suggestion to implement this as a flag is because it needs to be at the fingertips and first-class in the documentation.

johnrichardrinehart commented 2 years ago

@Kha Fair enough. But, I could also git stash push --keep-index which is (arguably) less history-destructive and easier to use (no commit message "needed"). But, I want to avoid multiple commands for one action: Build, but disregard the unstaged, yet tracked, changes.

dramforever commented 2 years ago

@johnrichardrinehart Sorry, I was talking from a more technical perspective. What I meant was just something like nix build .?index, putting the option to use the index as part of the URL, just like how we deal with explicit revisions path/to/repo?rev=.... The name index could use some bikeshedding though. An alternative could be staged

Under the hood this will be resolved to a git+file: URL because the path is in a Git repository, which is why I was talking about git+file:.

Instead of changing the interpretation of every git repository path (and probably even hg repository path), with a parameter only URLs that have ?index (or ?staged) have this behavior.

It's also clearer this way: If you nix build --from-index . and your flake has a input that's a dirty git repository, should that input also be taken from the git index? If you pass --from-index do dirty repositories in the nix registry get files taken from the index? It raises many more questions.

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info

andreabedini commented 11 months ago

Leaving some notes here just because I got nerd-sniped.

  1. You can export the index with git checkout-index --prefix=git-export-dir/ -a
  2. It could make sense to generalise nix to import "tree-ish" objects as they are still content addressable. Both commit and tags are "tree-ish" as they uniquely identify a tree
  3. The index is not a complete tree object but you can turn it into one with git write-tree