aboutsummaryrefslogtreecommitdiff

hm-reposync

hm-reposync is a module for home-manager that allows tracking and managing out-of-(nix)store git repositories. The module generates and installs in the users home.packages a shell script called reposync. This command allows managing multiple repositories at once (clone, pull, stow, and more). Read reposync.1 or run man reposync once installed for more info.

Examples

In flake.nix (home-manager as NixOS module in this example):

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";

    home-manager = {
      url = "github:nix-community/home-manager/release-25.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    reposync = {
      url = "git://git.tjkeller.xyz/hm-reposync";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { nixpkgs, ... }@inputs: let
    system = {
      # ...
    };
  in {
    nixosConfigurations = {
      example-host = nixpkgs.lib.nixosSystem {
        inherit system;
        # ...
        modules = [
          ./some-configuration.nix

          inputs.home-manager.nixosModules.home-manager {
            home-manager = {
              # ...
              useUserPackages = true;
              sharedModules = [
                inputs.reposync.hmModules.reposync
                ./some-home-configuration.nix
              ];
            };
          };
        ];
      };
    };
}

In home configuration:

reposync.enable = true;
reposync.outOfStoreGitRepository = {
  config = {
    # Default git server is github (https)
    repository = "github-user/dotconfig";
    target = "src/config";  # Relative to home directory
    extraCloneOptions = "--recurse-submodules";
    stow = {
      vim = {
        targetPrefix = config.xdg.configHome;
      };
      misc = {
        packages = "x11 zsh";
      };
    };
  };
  scripts = {
    # Default repository will be scripts in this case
    server = "https://git.tjkeller.xyz/";
    targetPrefix = "/home/my-user/src";  # Final target will be /home/my-user/src/scripts
    stow."*".target = ".local/bin";
  };
  hm-reposync = {
    enable = lib.mkDefault false;
    server = "https://git.tjkeller.xyz/";
  };
  awesome = {
    server = "https://git.tjkeller.xyz/";
    targetPrefix = config.xdg.configHome;
  };
};

Now the command reposync -a will sync all these repositories at once. It will clone them if they do not exist, and it will run pull to grab the latest changes IF there are no local changes. Individual repositories can be synced using reposync <repo>.

Stow is a first class citizen, stow --restow will be ran on the packages tracked in <repo>.stow.<package> whenever synced.