How to source git-prompt.sh?

Git package includes a git-prompt.sh script, which provides some functions for shell prompt customisation. The file is not included into PATH but is present on the system:

$ fd --glob *git-prompt.sh /nix
/nix/store/nj7k6hp58pdymc785jkiqm6ff3x5qyg0-system-path/share/bash-completion/completions/git-prompt.sh
/nix/store/x5l2jap67yd3mirxwlwcj76wiw281lyk-system-path/share/bash-completion/completions/git-prompt.sh
/nix/store/smkgs7gi61qh9bsvdmpq169q4frj68nj-system-path/share/bash-completion/completions/git-prompt.sh
/nix/store/vnrg6qx2ia1kn2iyqc57pg99h4bjb27w-system-path/share/bash-completion/completions/git-prompt.sh
/nix/store/v74hgl35vxm45db39dr7y6a8k9976z0r-git-2.38.0/share/bash-completion/completions/git-prompt.sh
/nix/store/v74hgl35vxm45db39dr7y6a8k9976z0r-git-2.38.0/share/git/contrib/completion/git-prompt.sh
/nix/store/zyy8w7rjvqwk3y136afwcj7y0yp6y01m-system-path/share/bash-completion/completions/git-prompt.sh
/nix/store/x0sydibl51f6dn9l52gn1ca3iiracllc-system-path/share/bash-completion/completions/git-prompt.sh
/nix/store/p381502dd80hxfknhv0xb81065f392y8-system-path/share/bash-completion/completions/git-prompt.sh

What would be the proper portable way to source the file?

Two approaches seem to be common from searching GitHub: either configuring bashrc with Nix and referring to the file as ${pkgs.git}/share/git/contrib/completion/git-prompt.sh or simply bundling it with the configuration. I would prefer keeping the same bashrc across NixOS and non-Nix systems for now.

This should already happen by default, assuming you don’t set programs.bash.enableCompletion to false, see this comment: https://github.com/NixOS/nixpkgs/blob/26eb67abc9a7370a51fcb86ece18eaf19ae9207f/nixos/modules/programs/bash/bash-completion.nix#L20

Normally nixos should add the git package’s share directory to XDG_DATA_DIRS, at least, by adding it to /run/current-system/sw/share. Maybe you override this?

1 Like

programs.bash.enableCompletion is set on my system. XDG_DATA_DIRS does not include git’s share folder but it does include /run/current-system/sw/share, which has the git’s completions linked correctly:

$ ls /run/current-system/sw/share/bash-completion/completions/git-prompt.sh
/run/current-system/sw/share/bash-completion/completions/git-prompt.sh@

However the comment explicitly says that the completions from XDG_DATA_DIRS are not sourced as this is done by bash itself. Here’s what I found in the bash-completion docs:

The completion files of the name <cmd> or <cmd>.bash, where <cmd> is
the name of the target command, are searched in the above completion
directories in order. The file that is found first is used. When no
completion file is found in any completion directories in this process, the
completion files of the name _<cmd> is next searched in the completion
directories in order.

Which explains why /run/current-system/sw/share/bash-completion/completions/git is sourced (whenever a completion is requested for a git command) but the freestanding git-prompt.sh at the same directory is not.

I think I’ll just conditionally source /run/current-system/sw/share/bash-completion/completions/git-prompt.sh in my bashrc.

Thanks for the hints!

1 Like

Interesting! Given the file is deliberately added to the completions directory, I don’t think this is intentional. It should probably be considered a bug, and an option added for it. Mind raising an issue upstream so we pick the maintainer’s brain about it too?

1 Like

Done, thanks for the suggestion and for helping to debug this.

https://github.com/NixOS/nixpkgs/issues/199046

1 Like

awesome! this is now an option git: add prompt.enable by ProminentRetail · Pull Request #265532 · NixOS/nixpkgs · GitHub

works great for bash but doesn’t source when I use zsh…hmmmm

Wouldn’t it be better if __git_ps1 (the function provided by git-prompt.sh) just worked automatically on any system with git in the environment.systemPackages list, instead of having to set the new programs.git.prompt.enable option?

This is what Debian does. If you look at the file list for the Debian git package you can see that it installs a file named /etc/bash_completion.d/git-prompt.

The equivalent thing in Nixpkgs would be if we modify the git package builder to copy git-prompt.sh from $out/share/git/contrib/completion/git-prompt.sh to $out/etc/bash_completion.d/. By default, the NixOS /etc/profile searches for etc/bash_completion.d/* scripts in the current Nix profiles and sources them. This behavior can be disabled by setting the programs.bash.enableCompletion option to false for people who want their shells to be a little faster.

Actually, programs.git.prompt.enable isn’t even working for me, but I’m not trying too hard to troubleshoot it or report a bug about it. I’d rather implement the simple solution described above, if people think it’s good.

–David

I ran into this problem and ended up solving it using Home Manager with the following config:

  programs.bash = {
    enable = true;
    enableCompletion = true;
    initExtra = ''
      # Load __git_ps1 bash command.
      . ~/.nix-profile/share/git/contrib/completion/git-prompt.sh
      # Optional: Also load git command completions for bash.
      . ~/.nix-profile/share/git/contrib/completion/git-completion.bash

      # Show working directory and git branch status in terminal shell.
      # Customize as desired for your shell prompt preferences.
      export PS1='\w $(__git_ps1 "(%s)") \$ '
    '';
  };

I wrote a more detailed explanation if you’re interested in more.