Is it possible to change the default git user config for a `devShell`?

I’m setting up a personal dev shell for some new contract work. The work is for a company where contractors have been given dedicated work emails.

I’m wondering if it’s possible to make it so that when I do:

nix develop .#my-work-shell

it will change the email for my default git user? Is something like this possible?

Currently I’m declaring my git user info within my home-manager configuration with something like:

  programs.git = {
    enable = true;
    userName = "username";
    userEmail = "email@domain.com";
  };

I’d like to override the userEmail, though only while within the scope of the dev shell above.

Any ideas or thoughts on how to approach this would be appreciated!

1 Like

You could probably use shellHook and the git config command (by default it sets configuration for the current repository, which is different from global config). That seems a bit hacky to me though, I’d personally just manually set those options on the repository.

Ah! Seems git has environment variables to configure this, which have priority over config values. I.e.:

shellHook = ''
    GIT_AUTHOR_EMAIL='email@workdomain.com'
'';

should work.

4 Likes

Nice! Just for the record, I used exactly this but with export, so:

shellHook = ''
    export GIT_AUTHOR_EMAIL='email@workdomain.com'
''

Edit: Oh but it’s not necessary it seems. Ignore this!

Heh. I had to double check whether export was required, too, but yes, the shellHook runs in the shell you will be using, so no export is required :wink:

1 Like

Not directly an answer to your question, though I have a similar problem and collect all my work related stuff in a separate base folder, I then configured git to use a different configuration when in that folder.

This way I do not have to remember setting it up correctly in the shell each time.

The Home-Manager style to configure that, looks like this:

3 Likes

Would it be possible to modify the Git’s Nix expression to make it customizable in a shell.nix, similar to how it can be done with Vim? As far as I know, Git is configured with an rc file and environment variables, just as Vim.

Have nothing against the accepted answer, but it would be nice to transfer my NixOS config (almost) verbatim to a shell.nix as I did with Vim.

edit: It would be nice to have a tmux-like hack available for this, but Git doesn’t have a switch similar to tmux -f.

You can do that with the GIT_CONFIG_GLOBAL env var instead.

Stackoverflow isn’t a reference manual, I really recommend looking at the actual documentation for things like this. Jokes about git man pages aside, high level stuff like this is nicely documented in man git.

2 Likes

Thanks! I ended up with the following:

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = [
    # ...
  ];

  GIT_CONFIG_GLOBAL =
    pkgs.writeText
      "git.conf"
      ''
      # https://git-scm.com/docs/git-config#_configuration_file
      # or copy-paste from where home-manager keeps it:
      # ~/.config/git/config
      ''
  ;

  shellHook = ''
    # stuff
  ''
}
NOTE TO FUTURE SELF

If a path is provided to GIT_CONFIG_GLOBAL, then it will be copied to the Nix store (no writeText needed)

For example:

GIT_CONFIG_GLOBAL = ./config_files/git.conf

writeText (and co.) becomes a derivation (i.e., a .drv file in the Nix store) so how can it be assigned to a shell variable as if it was the end result?

nix-repl> pkgs.writeText "lofa" ''
          falho
          vert
          lofa
          ''
«derivation /nix/store/572zrrh4jg2qimw8xfcjjnf75jkv0syp-lofa.drv»

I remember something about this in one of the manuals (that “intermediate” derivation will get instantiated or something), but can’t remember in which (and where)…

Why does GIT_CONFIG_GLOBAL work outside of shellHook?

I don’t think this is documented (see thread), but

  • variables in mkShell but outside shellHook will become ENVIRONMENT VARIABLES
  • variables inside shellHook become SHELL VARIABLES (unless explicitly exported)

So the example above is equivalent to

{ pkgs ? import <nixpkgs> {} }:

pkgs.mkShell {
  buildInputs = [
    # ...
  ];

  shellHook =
    let
      gitConf =
        pkgs.writeText
          "git.conf"
          ''
          # https://git-scm.com/docs/git-config#_configuration_file
          # or copy-paste from where home-manager keeps it:
          # ~/.config/git/config
          ''
      ;
    in
      ''
      # That's Nix's string interpolation!
      #                         VV.......V
      export GIT_CONFIG_GLOBAL="${gitConf}"
      #                         ^^.......^
      
      # stuff
      ''
  ;
}

(Use ''\{..} for Bash’s string interpolation.)

2 Likes