GIT-SHELL(1)

💅 GIT-SHELL(1) — like, the whole manual, but make it make sense

okay bestie, so this is a page from the Git Manual and it's about git-shell, and honestly? it's the bouncer at the club that is your SSH access. let's get into it 🎀


✨ NAME ✨

git-shell — the restricted login shell for Git-only SSH access. that's it, that's the vibe. it's giving "you can come in, but only to do Git things" 🫶


✨ SYNOPSIS ✨

chsh -s $(command -v git-shell) <user>
git clone <user>@localhost:/path/to/repo.git
ssh <user>@localhost

no cap, those three lines are the whole personality. 💅


✨ DESCRIPTION ✨

so basically: this is a login shell for SSH accounts that hands out restricted Git access. it permits execution only of the server-side Git commands that implement the pull/push functionality — plus any custom commands that live in a subdirectory named git-shell-commands in the user's home directory. lowkey iconic permission design, ngl. 🔥


✨ COMMANDS ✨

git shell accepts the following commands after the -c option:

  • git receive-pack <argument>, git upload-pack <argument>, git upload-archive <argument> — these call the corresponding server-side command so the client's git push, git fetch, or git archive --remote request actually works. yes bestie, one for each. 🦋
  • cvs server — imitates a CVS server. see git-cvsserver(1). vintage! 💀

if a ~/git-shell-commands directory is present, git shell will also handle other, custom commands by running "git-shell-commands/<command> <arguments>" from the user's home directory. so you literally get to build your own little command menu. main character energy. 👑


✨ INTERACTIVE USE ✨

by default, the commands above can be executed only with the -c option — the shell is not interactive. sad but true 😭

BUT. if a ~/git-shell-commands directory is present, git shell can also be run interactively (with no arguments). and if a help command is present in the git-shell-commands directory, it is run to give the user an overview of allowed actions. then you get a "git> " prompt, at which one can enter any of the commands from the git-shell-commands directory, or exit to close the connection. the prompt is literally "git> " — with the space, don't come for me. ✨

generally this mode is used as an administrative interface to let users list repositories they have access to, create, delete, or rename repositories, or change repository descriptions and permissions. it's giving tiny admin dashboard. 💖

if a no-interactive-login command exists, then it is run and the interactive shell is aborted. not me showing you the door 🚪


✨ EXAMPLES ✨

to disable interactive logins, displaying a greeting instead:

$ chsh -s /usr/bin/git-shell
$ mkdir $HOME/git-shell-commands
$ cat >$HOME/git-shell-commands/no-interactive-login <<\EOF
#!/bin/sh
printf '%s\n' "Hi $USER! You've successfully authenticated, but I do not"
printf '%s\n' "provide interactive shell access."
exit 128
EOF
$ chmod +x $HOME/git-shell-commands/no-interactive-login
ngl that exit 128 is doing the heavy lifting. 👀

to enable git-cvsserver access:

highkey important — this should generally have the no-interactive-login example above as a prerequisite, because creating the git-shell-commands directory allows interactive logins. so like, lock the front door before you open the side door, okay? 🙈

$ cat >$HOME/git-shell-commands/cvs <<\EOF
if ! test $# = 1 && test "$1" = "server"
then
        echo >&2 "git-cvsserver only handles \"server\""
        exit 1
fi
exec git cvsserver server
EOF
$ chmod +x $HOME/git-shell-commands/cvs

✨ SEE ALSO ✨

👑 go read them, i'll wait.


✨ GIT ✨

part of the git(1) suite. obviously. 💜


🌸 okay that's the whole page, and yes she ate — this was written for Git 2.56.0, dated 2026-09-27, and it lives at the top of the page as GIT-SHELL(1) / Git Manual / GIT-SHELL(1) because that's just how manpages dress themselves. mwah 💋 🎀

📦 where this page comes from