Skip to content

fetchgit: fetch tags reproducibly and allow unstable version package to use git describe#466743

Draft
ShamrockLee wants to merge 13 commits intoNixOS:masterfrom
ShamrockLee:fetchgit-postCheckout-fetchTags
Draft

fetchgit: fetch tags reproducibly and allow unstable version package to use git describe#466743
ShamrockLee wants to merge 13 commits intoNixOS:masterfrom
ShamrockLee:fetchgit-postCheckout-fetchTags

Conversation

@ShamrockLee
Copy link
Contributor

@ShamrockLee ShamrockLee commented Dec 1, 2025

Description

This PR addresses the unsolved question of #465497 about the reproducible git describe for packages with unstable versions.

  • This PR allows specifying fetchTags as an attribute set, and changes its default to { }, allowing reproducible fetching of additional tags from the main module and submodules.
    • Unlike fetchTags = true, specifying fetchTags as an attribute set does not imply leaveDotGit = true. This encourages the use of postCheckout for better hash stability.
    • The corresponding command-line arguments for nix-prefetch-git is --fetch-tag TAG, which can be specified multiple times.
  • This PR allows fetchgit to take both rev and tag simultaneously. In such scenario, the rev will be observed as the revision to fetch, and the tag will be added to the fetchTags list.

Example use case:

{
  lib,
  stdenv,
  fetchgit,
}:
let
  getPreviousStableVersion =
    v:
    let
      matched = lib.match "(.*)-unstable-[0-9]{4}-[0-9]{2}-[0-9]{2}" v;
    in
    if matched == null then v else lib.head matched;
in
stdenv.mkDerivation {
  pname = "my-package";
  version = "0.1.0-unstable-2024-12-31";
  src = fetchgit {
    url = "https://example.com/source.git";
    rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a"
    tag = "v${getPreviousStableVersion finalAttrs.version}";
    hash = "sha256-7DszvbCNTjpzGRmpIVAWXk20P0/XTrWZ79KSOGLrUWY=";
    postCheckout = ''
      git describe | tee git_describe_output.txt
    '';
  };
}

This PR depends on the following PRs:

The diff will be shorter once the depending PR is merged.

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

Add a 👍 reaction to pull requests you find important.

@ShamrockLee ShamrockLee changed the title Allows fetchgit: fetch tags reproducibly and allow unstable version package to use git describe Dec 1, 2025
@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. 10.rebuild-darwin: 11-100 This PR causes between 11 and 100 packages to rebuild on Darwin. 6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) labels Dec 1, 2025
@ony
Copy link
Contributor

ony commented Dec 7, 2025

What about sub-modules?
From example I see that it is inferred easily from version of package. But sub-modules may have own version and not always listed in derivation explicitly.

When considering interface for tags in sub-modules, worth to think about how they are going to be updated since I was not able to find update scripts that do something for sub-modules.

Asking because faced this problem in #461391 where root package vends bundled in sub-module having own version.

@ShamrockLee ShamrockLee force-pushed the fetchgit-postCheckout-fetchTags branch from 747755c to 1b80835 Compare December 9, 2025 04:39
@ShamrockLee
Copy link
Contributor Author

Rebased after merging PR #462032.

@ShamrockLee ShamrockLee force-pushed the fetchgit-postCheckout-fetchTags branch from 1b80835 to 005d8ae Compare December 9, 2025 11:36
@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented Dec 9, 2025

@ony I changed the new fetchTags interface to an attribute set that looks like

fetchgit {
  fetchTags = {
    # For the main repo
    "" = [ "tag1" ];
    # For submodule at path/to/nlohmann_json
    "path/to/nlohmann_json" = [ "tag2" "tag3" ];
  };
}

Update:
The subpaths no longer have a slash (/) prefiix. The subpath for the main repository is now an empty string ("").

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 101-500 This PR causes between 101 and 500 packages to rebuild on Linux. 10.rebuild-darwin: 101-500 This PR causes between 101 and 500 packages to rebuild on Darwin. and removed 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. 10.rebuild-darwin: 11-100 This PR causes between 11 and 100 packages to rebuild on Darwin. labels Dec 9, 2025
@ShamrockLee ShamrockLee force-pushed the fetchgit-postCheckout-fetchTags branch 2 times, most recently from 3656578 to 3a5ab36 Compare December 9, 2025 14:56
@ony
Copy link
Contributor

ony commented Dec 9, 2025

@ony I changed the new fetchTags interface to an attribute set that looks like

Thank you. What about inferring those tags?
And how auto-update scripts¹ will integrate with this?

As I mentioned before they are not necessary in relation with package version as root source likely is. And thus they have to be hard-coded if they specified explicitly.


¹ From what I saw it seems that automatic updates focused on version and hash updates. See "Automatic package updates" section in README.md, "Nixpkgs/Update Scripts" wiki, and nixpkgs-update documentation.

@ShamrockLee ShamrockLee force-pushed the fetchgit-postCheckout-fetchTags branch 2 times, most recently from bbb31dd to 0d34acf Compare December 10, 2025 16:30
@ShamrockLee
Copy link
Contributor Author

ShamrockLee commented Dec 10, 2025

What about inferring those tags?\nAnd how auto-update scripts will integrate with this?

nix-prefetch-git now takes --fetch-submodule-tags subpath to fetch all tags for a submodule. The corresponding fetchTags represintation is { "path/to/submodule" = true; }.

The drawback is NixOS/nix#14675 preventing us from specifying { fetchTags = { "" = true; }.

Update:

@ShamrockLee ShamrockLee force-pushed the fetchgit-postCheckout-fetchTags branch 2 times, most recently from 655eb6f to 5625e5d Compare December 10, 2025 18:52
@nixpkgs-ci nixpkgs-ci bot added the 2.status: merge conflict This PR has merge conflicts with the target branch label Dec 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2.status: merge conflict This PR has merge conflicts with the target branch 6.topic: fetch Fetchers (e.g. fetchgit, fetchsvn, ...) 10.rebuild-darwin: 101-500 This PR causes between 101 and 500 packages to rebuild on Darwin. 10.rebuild-linux: 101-500 This PR causes between 101 and 500 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants