As mentioned in Chapter 6, Git can access remote repositories for push and pull using different network protocols; the most common are HTTP(S), SSH, and the native Git protocol. Especially if the remote repository accepts push requests, the access protocol may require you to identify yourself in order to grant access; this is called “authentication,” and may be accomplished in various ways, such as by providing a username and password. The Git protocol does not support authentication, so this is usually done via HTTP or SSH; the native Git server, accessed on port 9418 with the URL scheme
git://, is used almost exclusively for read-only access to repositories (for which it is a good choice, since it is fast and easy to set up).
The question of how to configure the server side for these protocols generally is well beyond the scope of this text; entire books have been written on SSH, the Apache web server, the Windows IIS web server, etc. However, we will touch on a few common cases from the client perspective, and on some Git features that help with this.
Git runs ssh, or the program given by the environment variable
GIT_SSH, to log into the remote host and access the repository by running the appropriate remote command:
git upload-pack for pull, and
git receive-pack for push. The local and remote Git programs then communicate over the SSH channel to perform the requested operation. For example, when asked to pull from the repository
email@example.com:dance/monkey, Git runs this command:
ssh firstname.lastname@example.org git-upload-pack dance/monkey
This logs into the host
sprockets.tv with the username
dieter, and runs the remote command
git-upload-pack dance/monkey. If the host is Unix, usually this means that there must be a user account named
dieter on that host,
git-upload-pack must be in the program-search path on the remote side (the PATH environment variable), and the remote repository must be in a subdirectory of the
dieter account’s home directory named dance/monkey. You can refer to any directory to which the remote account has access by using a complete pathname with a leading slash (e.g.,
SSH will prompt you for a password if necessary, but it may be very inconvenient to do this repeatedly, so you may want some form of automatic authentication for this connection: a method by which you can type your passphrase just once and allow many subsequent Git commands. There are several different options for this, but the most common is SSH public-key authentication.
All the details we are about to give regarding SSH assume the simplest scenario: the Unix OpenSSH software on both client and server in the most usual, plain configuration. Although this is very common, any or all of these may be entirely different depending on the operating systems, SSH software, and system configurations involved. Similarly, SSH by itself and security in general are complex topics. There are many different ways of accomplishing even this simple task, with varying implications with regard to security, and this simple example is not meant to endorse any particular one. When in doubt, consult a security expert or the sysadmins of the hosts in question.
You can generate a new SSH public key thus if you don’t already have one:
$ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in .ssh/id_rsa. Your public key has been saved in .ssh/id_rsa.pub. ...
The “passphrase” is just another name for a password, emphasizing the fact that you can use an entire phrase with spaces and punctuation, not just a single word. You should generally not just leave this blank; that means that anyone who gets hold of the private key file id_rsa will have access to any SSH accounts protected with this key. It’s like putting your password in a file; don’t do it unless you really know what you’re doing (or really don’t care about security).
You then send your public key—the contents of the file ~/.ssh/id_rsa.pub—to the server administrator, asking him to authorize your key for login to the remote account; this usually means placing it in ~/.ssh/authorized_keys in the home directory of the account, with appropriate ownership and permissions. When this is done, SSH will prompt you for the key passphrase instead:
$ git pull Enter passphrase for key '/home/res/.ssh/id_rsa':
Enter your passphrase to test whether the setup is working correctly—though so far this is not much of an improvement in convenience; you’re still being prompted to enter something for every Git command accessing the remote repository. The final step is to use the SSH “agent” to get automatic authentication:
# Test whether you have a running agent. $ ssh-add -l >& /dev/null; [ $? = 2 ] && echo no-agent no-agent # If not, start one. $ eval $(ssh-agent) # Now, add your key to the agent. $ ssh-add Enter passphrase for /home/res/.ssh/id_rsa: Identity added: /home/res/.ssh/id_rsa (.ssh/id_rsa)
On some modern Unix-based systems, you may not have to do any of this—for example, OS X starts an SSH agent for you when you log in, and SSH prompts you for your key passphrase with a graphical dialog box and automatically adds it to the agent on first use.
Once your key is loaded in the agent, you should be able to use Git to access this repository without giving your passphrase, for the duration of your current login session on the client computer.
You can also use this style of URL for SSH:
A distinction to keep in mind is that, unlike the earlier style, the path given here is not relative to the remote account’s home directory, but rather is absolute. You can get a relative path by prefixing the path with
~. For example:
although this may depend on the shell used by the remote account.
A web server providing access to a Git repository may also be set to require authentication. Although more sophisticated mechanisms are available, including Kerberos and public-key certificates, the most common approach with HTTP is still to require a simple username and password. This complicates automatic authentication, but Git has its own framework for managing and providing such credentials.
But you can also set it separately, like so:
$ git config --global credential.'https://sprockets.tv/'.username dieter
Git has a mechanism called “credential helpers,” which stores passwords in various ways for more convenient use. One such helper, named
cache, is similar to ssh-agent and caches your password in memory for use by Git. It is not used by default; to enable it, do:
$ git config --global credential.helper cache
Once you do this, Git should prompt you only once in a given login session for the password associated with any particular URL; when you provide it, Git stores it in the running credential cache agent, and subsequent commands automatically obtain it from there. If you look, you can see the agent process:
$ ps -e | grep git-cred | grep -v grep 33078 ttys001 0:00.01 git-credential-cache--daemon /home/res/.git-credential-cache/socket
Git communicates with the agent via the socket shown on the agent command line.
There is another standard credential helper named
store, which simply stores the password in a file on disk (~/.git-credentials). You shouldn’t do this for interactive use, but it is appropriate for automated processes that need to run Git and use password authentication, so long as adequate care is taken in protecting the host system and setting permissions on that file. You can also use the cache helper with automated processes if that level of security is not enough, but a human will have to enter the password once after the machine boots in order to add it to the cache, so this is not the right approach if the system in question must be able to start unattended.
The Git credential mechanism is extensible, and there are third-party helpers available that connect with platform-specific security features. For example, the helper
osxkeychain stores passwords in the OS X “keychain,” the standard credential manager for the Mac. It is included with the versions of Git installed by the Apple Xcode developer tools or by MacPorts. Just enable it with:
$ git config --global credential.helper osxkeychain
For more detail, see: