From 846f5cb3d535ba6b491789548c1f1cadccc95430 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Tue, 10 Jun 2014 09:54:51 -0700 Subject: [PATCH 01/13] add smart http docs, consolidate the http sections --- book/04-git-server/1-git-server.asc | 130 +++++++++++++++------------- 1 file changed, 71 insertions(+), 59 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 57112fe66..1304d72b0 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -21,11 +21,9 @@ In the simplest terms, a bare repository is the contents of your project’s `.g === The Protocols -Git can use four major network protocols to transfer data: Local, Secure Shell (SSH), Git, and HTTP. +Git can use four major protocols to transfer data: Local, HTTP, Secure Shell (SSH) and Git. Here we’ll discuss what they are and in what basic circumstances you would want (or not want) to use them. -It’s important to note that with the exception of the HTTP protocols, all of these require Git to be installed and working on the server. - ==== Local Protocol The most basic is the _Local protocol_, in which the remote repository is in another directory on disk. @@ -73,12 +71,75 @@ It’s also important to mention that this isn’t necessarily the fastest optio A local repository is fast only if you have fast access to the data. A repository on NFS is often slower than the repository over SSH on the same server, allowing Git to run off local disks on each system. +==== The HTTP Protocols + +Git can communicate over HTTP in two different modes. +Prior to Git 1.6.6 there was only one way it could do this. +Since there are now two different protocols that operate over HTTP, we refer to them as the ``dumb'' and the ``smart'' protocols. We'll cover the newer ``smart'' HTTP protocol first. + +===== Smart HTTP + +The ``smart'' HTTP protocol operates very similarly to the SSH or Git protocols but runs over standard HTTP/S ports and can use various HTTP authentication mechanisms, meaning it's often easier on the user than something like SSH, since you can use things like username/password basic authentication rather than having to set up SSH keys. + +It has probably become the most popular way to use Git now, since it can be set up to both serve anonymously like the `git://` protocol, and can also be pushed over with authentication like the SSH protocol. Instead of having to set up different URLs for these things, you can now use a single URL for both. If you try to push and the repository requires authentication (which it normally should), the server can prompt for a username and password. The same goes for read access. + +In fact, for services like GitHub, the URL you use to view the repository online (for example, ``https://github.com/schacon/simplegit``) is the same URL you can use to clone and, if you have access, push over. + +===== Dumb HTTP + +Git will also fall back to a simpler ``dumb'' HTTP protocol should the server not respond with a Git process. +The beauty of the Dumb HTTP protocol is the simplicity of setting it up. +Basically, all you have to do is put the bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you’re done (See <<_git_hooks>>). +At that point, anyone who can access the web server under which you put the repository can also clone your repository. +To allow read access to your repository over HTTP, do something like this: + + $ cd /var/www/htdocs/ + $ git clone --bare /path/to/git_project gitproject.git + $ cd gitproject.git + $ mv hooks/post-update.sample hooks/post-update + $ chmod a+x hooks/post-update + +That’s all. +The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. +This command is run when you push to this repository over SSH; then, other people can clone via something like + + $ git clone http://example.com/gitproject.git + +In this particular case, we’re using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server – just put the bare repository in its path. +The Git data is served as basic static files (see <<_git_internals>> for details about exactly how it’s served). + +===== The Pros + +The simplicity of having a single URL for all types of access and having the server prompt only when authentication is needed makes things very simple for the end user. +Being able to authenticate with a username and password is also a big advantage over SSH, since users don't have to generate SSH keys locally and upload their public key to the server before being able to interact with it. +For less sophisticated users, or users on systems where SSH is less common, this is a major advantage in usability. +It is also a very fast and efficient protocol, similar to the SSH one. + +The upside of using the HTTP protocol is that it’s easy to set up. +Running the handful of required commands gives you a simple way to give the world read access to your Git repository. +It takes only a few minutes to do. +The HTTP protocol also isn’t very resource intensive on your server. +Because it generally uses a static HTTP server to serve all the data, a normal Apache server can serve thousands of files per second on average – it’s difficult to overload even a small server. + +You can also serve your repositories read-only over HTTPS, which means you can encrypt the content transfer; or you can go so far as to make the clients use specific signed SSL certificates. +Generally, if you’re going to these lengths, it’s easier to use SSH public keys; but it may be a better solution in your specific case to use signed SSL certificates or other HTTP-based authentication methods for read-only access over HTTPS. + +Another nice thing is that HTTP is such a commonly used protocol that corporate firewalls are often set up to allow traffic through this port. + +===== The Cons + +Git over HTTP/S can be a little more tricky to set up compared to SSH on some servers. +Other than that, there is very little advantage that other protocols have over the ``Smart'' HTTP protocol for serving Git. + +The downside of serving your repository over HTTP is that it’s relatively inefficient for the client. +It generally takes a lot longer to clone or fetch from the repository, and you often have a lot more network overhead and transfer volume over HTTP than with any of the other network protocols. +Because it’s not as intelligent about transferring only the data you need – there is no dynamic work on the part of the server in these transactions – the HTTP protocol is often referred to as a _dumb_ protocol. +For more information about the differences in efficiency between the HTTP protocol and the other protocols, see <<_git_internals>>. + ==== The SSH Protocol -Probably the most common transport protocol for Git is SSH. +A common transport protocol for Git when self-hosting is over SSH. This is because SSH access to servers is already set up in most places – and if it isn’t, it’s easy to do. -SSH is also the only network-based protocol that you can easily read from and write to. -The other two network protocols (HTTP and Git) are generally read-only, so even if you have them available for the unwashed masses, you still need SSH for your own write commands. SSH is also an authenticated network protocol; and because it’s ubiquitous, it’s generally easy to set up and use. To clone a Git repository over SSH, you can specify ssh:// URL like this: @@ -94,8 +155,7 @@ You can also not specify a user, and Git assumes the user you’re currently log ===== The Pros The pros of using SSH are many. -First, you basically have to use it if you want authenticated write access to your repository over a network. -Second, SSH is relatively easy to set up – SSH daemons are commonplace, many network admins have experience with them, and many OS distributions are set up with them or have tools to manage them. +First, SSH is relatively easy to set up – SSH daemons are commonplace, many network admins have experience with them, and many OS distributions are set up with them or have tools to manage them. Next, access over SSH is secure – all data transfer is encrypted and authenticated. Last, like the Git and Local protocols, SSH is efficient, making the data as compact as possible before transferring it. @@ -104,7 +164,7 @@ Last, like the Git and Local protocols, SSH is efficient, making the data as com The negative aspect of SSH is that you can’t serve anonymous access of your repository over it. People must have access to your machine over SSH to access it, even in a read-only capacity, which doesn’t make SSH access conducive to open source projects. If you’re using it only within your corporate network, SSH may be the only protocol you need to deal with. -If you want to allow anonymous read-only access to your projects, you’ll have to set up SSH for you to push over but something else for others to pull over. +If you want to allow anonymous read-only access to your projects and also want to use SSH, you’ll have to set up SSH for you to push over but something else for others to pull over. ==== The Git Protocol @@ -126,60 +186,12 @@ It uses the same data-transfer mechanism as the SSH protocol but without the enc The downside of the Git protocol is the lack of authentication. It’s generally undesirable for the Git protocol to be the only access to your project. -Generally, you’ll pair it with SSH access for the few developers who have push (write) access and have everyone else use `git://` for read-only access. +Generally, you’ll pair it with SSH or HTTPS access for the few developers who have push (write) access and have everyone else use `git://` for read-only access. It’s also probably the most difficult protocol to set up. -It must run its own daemon, which is custom – we’ll look at setting one up in the ``Gitosis'' section of this chapter – it requires `xinetd` configuration or the like, which isn’t always a walk in the park. +It must run its own daemon, which requires `xinetd` configuration or the like, which isn’t always a walk in the park. It also requires firewall access to port 9418, which isn’t a standard port that corporate firewalls always allow. Behind big corporate firewalls, this obscure port is commonly blocked. -==== The HTTP/S Protocol - -Last we have the HTTP protocol. -The beauty of the HTTP or HTTPS protocol is the simplicity of setting it up. -Basically, all you have to do is put the bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you’re done (See <<_git_hooks>>). -At that point, anyone who can access the web server under which you put the repository can also clone your repository. -To allow read access to your repository over HTTP, do something like this: - - $ cd /var/www/htdocs/ - $ git clone --bare /path/to/git_project gitproject.git - $ cd gitproject.git - $ mv hooks/post-update.sample hooks/post-update - $ chmod a+x hooks/post-update - -That’s all. -The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. -This command is run when you push to this repository over SSH; then, other people can clone via something like - - $ git clone http://example.com/gitproject.git - -In this particular case, we’re using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server – just put the bare repository in its path. -The Git data is served as basic static files (see <<_git_internals>> for details about exactly how it’s served). - -It’s possible to make Git push over HTTP as well, although that technique isn’t as widely used and requires you to set up complex WebDAV requirements. -Because it’s rarely used, we won’t cover it in this book. -If you’re interested in using the HTTP-push protocols, you can read about preparing a repository for this purpose at `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt`. -One nice thing about making Git push over HTTP is that you can use any WebDAV server, without specific Git features; so, you can use this functionality if your web-hosting provider supports WebDAV for writing updates to your web site. - -===== The Pros - -The upside of using the HTTP protocol is that it’s easy to set up. -Running the handful of required commands gives you a simple way to give the world read access to your Git repository. -It takes only a few minutes to do. -The HTTP protocol also isn’t very resource intensive on your server. -Because it generally uses a static HTTP server to serve all the data, a normal Apache server can serve thousands of files per second on average – it’s difficult to overload even a small server. - -You can also serve your repositories read-only over HTTPS, which means you can encrypt the content transfer; or you can go so far as to make the clients use specific signed SSL certificates. -Generally, if you’re going to these lengths, it’s easier to use SSH public keys; but it may be a better solution in your specific case to use signed SSL certificates or other HTTP-based authentication methods for read-only access over HTTPS. - -Another nice thing is that HTTP is such a commonly used protocol that corporate firewalls are often set up to allow traffic through this port. - -===== The Cons - -The downside of serving your repository over HTTP is that it’s relatively inefficient for the client. -It generally takes a lot longer to clone or fetch from the repository, and you often have a lot more network overhead and transfer volume over HTTP than with any of the other network protocols. -Because it’s not as intelligent about transferring only the data you need – there is no dynamic work on the part of the server in these transactions – the HTTP protocol is often referred to as a _dumb_ protocol. -For more information about the differences in efficiency between the HTTP protocol and the other protocols, see <<_git_internals>>. - === Getting Git on a Server In order to initially set up any Git server, you have to export an existing repository into a new bare repository – a repository that doesn’t contain a working directory. From b14d6543abb8076e85a7ad7dcb7c9c0c92ebf9a5 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 10:32:12 -0700 Subject: [PATCH 02/13] rework documentation on http protocol --- book/04-git-server/1-git-server.asc | 35 +++++++++++++---------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 1304d72b0..ee4dae133 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -5,7 +5,6 @@ However, in order to do any collaboration in Git, you’ll need to have a remote Although you can technically push changes to and pull changes from individuals’ repositories, doing so is discouraged because you can fairly easily confuse what they’re working on if you’re not careful. Furthermore, you want your collaborators to be able to access the repository even if your computer is offline – having a more reliable common repository is often useful. Therefore, the preferred method for collaborating with someone is to set up an intermediate repository that you both have access to, and push to and pull from that. -We’ll refer to this repository as a ``Git server''; but you’ll notice that it generally takes a tiny amount of resources to host a Git repository, so you’ll rarely need to use an entire server for it. Running a Git server is simple. First, you choose which protocols you want your server to communicate with. @@ -74,8 +73,11 @@ A repository on NFS is often slower than the repository over SSH on the same ser ==== The HTTP Protocols Git can communicate over HTTP in two different modes. -Prior to Git 1.6.6 there was only one way it could do this. -Since there are now two different protocols that operate over HTTP, we refer to them as the ``dumb'' and the ``smart'' protocols. We'll cover the newer ``smart'' HTTP protocol first. +Prior to Git 1.6.6 there was only one way it could do this and it was very simple and generally read-only. +In version 1.6.6 a new, smarter protocol was introduced that involved Git being able to intelligently negotiate data transfer in a manner similar to how it does over SSH. +In the last few years, this new HTTP protocol has become very popular since it's simpler for the user and smarter about how it communicates. +The newer version is often referred to as the ``Smart'' HTTP protocol and the older way as ``Dumb'' HTTP. +We'll cover the newer ``smart'' HTTP protocol first. ===== Smart HTTP @@ -83,13 +85,14 @@ The ``smart'' HTTP protocol operates very similarly to the SSH or Git protocols It has probably become the most popular way to use Git now, since it can be set up to both serve anonymously like the `git://` protocol, and can also be pushed over with authentication like the SSH protocol. Instead of having to set up different URLs for these things, you can now use a single URL for both. If you try to push and the repository requires authentication (which it normally should), the server can prompt for a username and password. The same goes for read access. -In fact, for services like GitHub, the URL you use to view the repository online (for example, ``https://github.com/schacon/simplegit``) is the same URL you can use to clone and, if you have access, push over. +In fact, for services like GitHub, the URL you use to view the repository online (for example, ``https://github.com/schacon/simplegit'') is the same URL you can use to clone and, if you have access, push over. ===== Dumb HTTP -Git will also fall back to a simpler ``dumb'' HTTP protocol should the server not respond with a Git process. +If the server does not respond with a Git HTTP smart service, the Git client will try to fall back to the simpler ``dumb'' HTTP protocol. +The Dumb protocol expects the bare Git repository to be served like normal files from the web server. The beauty of the Dumb HTTP protocol is the simplicity of setting it up. -Basically, all you have to do is put the bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you’re done (See <<_git_hooks>>). +Basically, all you have to do is put a bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you’re done (See <<_git_hooks>>). At that point, anyone who can access the web server under which you put the repository can also clone your repository. To allow read access to your repository over HTTP, do something like this: @@ -101,40 +104,34 @@ To allow read access to your repository over HTTP, do something like this: That’s all. The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. -This command is run when you push to this repository over SSH; then, other people can clone via something like +This command is run when you push to this repository (over SSH perhaps); then, other people can clone via something like $ git clone http://example.com/gitproject.git In this particular case, we’re using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server – just put the bare repository in its path. The Git data is served as basic static files (see <<_git_internals>> for details about exactly how it’s served). +Generally you would either choose to run a read/write Smart HTTP server or simply have the files accessible as read-only in the Dumb manner. It's rare to run a mix of the two services. + ===== The Pros +We'll concentrate on the pros of the Smart version of the HTTP protocol. + The simplicity of having a single URL for all types of access and having the server prompt only when authentication is needed makes things very simple for the end user. Being able to authenticate with a username and password is also a big advantage over SSH, since users don't have to generate SSH keys locally and upload their public key to the server before being able to interact with it. For less sophisticated users, or users on systems where SSH is less common, this is a major advantage in usability. It is also a very fast and efficient protocol, similar to the SSH one. -The upside of using the HTTP protocol is that it’s easy to set up. -Running the handful of required commands gives you a simple way to give the world read access to your Git repository. -It takes only a few minutes to do. -The HTTP protocol also isn’t very resource intensive on your server. -Because it generally uses a static HTTP server to serve all the data, a normal Apache server can serve thousands of files per second on average – it’s difficult to overload even a small server. - You can also serve your repositories read-only over HTTPS, which means you can encrypt the content transfer; or you can go so far as to make the clients use specific signed SSL certificates. -Generally, if you’re going to these lengths, it’s easier to use SSH public keys; but it may be a better solution in your specific case to use signed SSL certificates or other HTTP-based authentication methods for read-only access over HTTPS. -Another nice thing is that HTTP is such a commonly used protocol that corporate firewalls are often set up to allow traffic through this port. +Another nice thing is that HTTP/S are such commonly used protocols that corporate firewalls are often set up to allow traffic through these ports. ===== The Cons Git over HTTP/S can be a little more tricky to set up compared to SSH on some servers. Other than that, there is very little advantage that other protocols have over the ``Smart'' HTTP protocol for serving Git. -The downside of serving your repository over HTTP is that it’s relatively inefficient for the client. -It generally takes a lot longer to clone or fetch from the repository, and you often have a lot more network overhead and transfer volume over HTTP than with any of the other network protocols. -Because it’s not as intelligent about transferring only the data you need – there is no dynamic work on the part of the server in these transactions – the HTTP protocol is often referred to as a _dumb_ protocol. -For more information about the differences in efficiency between the HTTP protocol and the other protocols, see <<_git_internals>>. +If you're using HTTP for authenticated pushing, credential caching is sometimes more complicated than using keys over SSH. There are however several credential caching tools you can use, including Keychain access on OSX and Credential Manager on Windows, to make this pretty painless. ==== The SSH Protocol From 323c1bd25dd20c4e508c2a867f8f223323fc5585 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 10:59:51 -0700 Subject: [PATCH 03/13] sourcify all the shell examples --- book/04-git-server/1-git-server.asc | 416 ++++++++++++++++++---------- 1 file changed, 271 insertions(+), 145 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index ee4dae133..fc3df6f05 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -33,11 +33,17 @@ If you have a shared mounted filesystem, then you can clone, push to, and pull f To clone a repository like this or to add one as a remote to an existing project, use the path to the repository as the URL. For example, to clone a local repository, you can run something like this: - $ git clone /opt/git/project.git +[source,shell] +---- +$ git clone /opt/git/project.git +---- Or you can do this: - $ git clone file:///opt/git/project.git +[source,shell] +---- +$ git clone file:///opt/git/project.git +---- Git operates slightly differently if you explicitly specify `file://` at the beginning of the URL. If you just specify the path, Git tries to use hardlinks or directly copy the files it needs. @@ -47,7 +53,10 @@ We’ll use the normal path here because doing so is almost always faster. To add a local repository to an existing Git project, you can run something like this: - $ git remote add local_proj /opt/git/project.git +[source,shell] +---- +$ git remote add local_proj /opt/git/project.git +---- Then, you can push to and pull from that remote as though you were doing so over a network. @@ -96,17 +105,23 @@ Basically, all you have to do is put a bare Git repository under your HTTP docum At that point, anyone who can access the web server under which you put the repository can also clone your repository. To allow read access to your repository over HTTP, do something like this: - $ cd /var/www/htdocs/ - $ git clone --bare /path/to/git_project gitproject.git - $ cd gitproject.git - $ mv hooks/post-update.sample hooks/post-update - $ chmod a+x hooks/post-update +[source,shell] +---- +$ cd /var/www/htdocs/ +$ git clone --bare /path/to/git_project gitproject.git +$ cd gitproject.git +$ mv hooks/post-update.sample hooks/post-update +$ chmod a+x hooks/post-update +---- That’s all. The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. This command is run when you push to this repository (over SSH perhaps); then, other people can clone via something like - $ git clone http://example.com/gitproject.git +[source,shell] +---- +$ git clone https://example.com/gitproject.git +---- In this particular case, we’re using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server – just put the bare repository in its path. The Git data is served as basic static files (see <<_git_internals>> for details about exactly how it’s served). @@ -141,11 +156,17 @@ SSH is also an authenticated network protocol; and because it’s ubiquitous, it To clone a Git repository over SSH, you can specify ssh:// URL like this: - $ git clone ssh://user@server:project.git +[source,shell] +---- +$ git clone ssh://user@server:project.git +---- Or you can not specify a protocol – Git assumes SSH if you aren’t explicit: - $ git clone user@server:project.git +[source,shell] +---- +$ git clone user@server:project.git +---- You can also not specify a user, and Git assumes the user you’re currently logged in as. @@ -196,8 +217,12 @@ This is generally straightforward to do. In order to clone your repository to create a new bare repository, you run the clone command with the `--bare` option. By convention, bare repository directories end in `.git`, like so: - $ git clone --bare my_project my_project.git - Initialized empty Git repository in /opt/projects/my_project.git/ +[source,shell] +---- +$ git clone --bare my_project my_project.git +Cloning into bare repository 'my_project.git'... +done. +---- The output for this command is a little confusing. Since `clone` is basically a `git init` then a `git fetch`, we see some output from the `git init` part, which creates an empty directory. @@ -206,7 +231,10 @@ You should now have a copy of the Git directory data in your `my_project.git` di This is roughly equivalent to something like - $ cp -Rf my_project/.git my_project.git +[source,shell] +---- +$ cp -Rf my_project/.git my_project.git +---- There are a couple of minor differences in the configuration file; but for your purpose, this is close to the same thing. It takes the Git repository by itself, without a working directory, and creates a directory specifically for it alone. @@ -217,18 +245,27 @@ Now that you have a bare copy of your repository, all you need to do is put it o Let’s say you’ve set up a server called `git.example.com` that you have SSH access to, and you want to store all your Git repositories under the `/opt/git` directory. You can set up your new repository by copying your bare repository over: - $ scp -r my_project.git user@git.example.com:/opt/git +[source,shell] +---- +$ scp -r my_project.git user@git.example.com:/opt/git +---- At this point, other users who have SSH access to the same server which has read-access to the `/opt/git` directory can clone your repository by running - $ git clone user@git.example.com:/opt/git/my_project.git +[source,shell] +---- +$ git clone user@git.example.com:/opt/git/my_project.git +---- If a user SSHs into a server and has write access to the `/opt/git/my_project.git` directory, they will also automatically have push access. Git will automatically add group write permissions to a repository properly if you run the `git init` command with the `--shared` option. - $ ssh user@git.example.com - $ cd /opt/git/my_project.git - $ git init --bare --shared +[source,shell] +---- +$ ssh user@git.example.com +$ cd /opt/git/my_project.git +$ git init --bare --shared +---- You see how easy it is to take a Git repository, create a bare version, and place it on a server to which you and your collaborators have SSH access. Now you’re ready to collaborate on the same project. @@ -274,24 +311,30 @@ First, you should check to make sure you don’t already have a key. By default, a user’s SSH keys are stored in that user’s `~/.ssh` directory. You can easily check to see if you have a key already by going to that directory and listing the contents: - $ cd ~/.ssh - $ ls - authorized_keys2 id_dsa known_hosts - config id_dsa.pub +[source,shell] +---- +$ cd ~/.ssh +$ ls +authorized_keys2 id_dsa known_hosts +config id_dsa.pub +---- You’re looking for a pair of files named something and something.pub, where the something is usually `id_dsa` or `id_rsa`. The `.pub` file is your public key, and the other file is your private key. If you don’t have these files (or you don’t even have a `.ssh` directory), you can create them by running a program called `ssh-keygen`, which is provided with the SSH package on Linux/Mac systems and comes with the MSysGit package on Windows: - $ ssh-keygen - Generating public/private rsa key pair. - Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): - Enter passphrase (empty for no passphrase): - Enter same passphrase again: - Your identification has been saved in /Users/schacon/.ssh/id_rsa. - Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub. - The key fingerprint is: - 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local +[source,shell] +---- +$ ssh-keygen +Generating public/private rsa key pair. +Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): +Enter passphrase (empty for no passphrase): +Enter same passphrase again: +Your identification has been saved in /Users/schacon/.ssh/id_rsa. +Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub. +The key fingerprint is: +43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local +---- First it confirms where you want to save the key (`.ssh/id_rsa`), and then it asks twice for a passphrase, which you can leave empty if you don’t want to type a password when you use the key. @@ -299,13 +342,16 @@ Now, each user that does this has to send their public key to you or whoever is All they have to do is copy the contents of the `.pub` file and e-mail it. The public keys look something like this: - $ cat ~/.ssh/id_rsa.pub - ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU - GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 - Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA - t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En - mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx - NrRFi9wrf+M7Q== schacon@agadorlaptop.local +[source,shell] +---- +$ cat ~/.ssh/id_rsa.pub +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU +GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 +Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA +t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En +mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx +NrRFi9wrf+M7Q== schacon@agadorlaptop.local +---- For a more in-depth tutorial on creating an SSH key on multiple operating systems, see the GitHub guide on SSH keys at `http://github.com/guides/providing-your-ssh-key`. @@ -316,55 +362,73 @@ In this example, you’ll use the `authorized_keys` method for authenticating yo We also assume you’re running a standard Linux distribution like Ubuntu. First, you create a 'git' user and a `.ssh` directory for that user. - $ sudo adduser git - $ su git - $ cd - $ mkdir .ssh +[source,shell] +---- +$ sudo adduser git +$ su git +$ cd +$ mkdir .ssh +---- Next, you need to add some developer SSH public keys to the `authorized_keys` file for that user. Let’s assume you’ve received a few keys by e-mail and saved them to temporary files. Again, the public keys look something like this: - $ cat /tmp/id_rsa.john.pub - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L - ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k - Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez - Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv - O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq - dAv8JggJICUvax2T9va5 gsg-keypair +[source,shell] +---- +$ cat /tmp/id_rsa.john.pub +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L +ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k +Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez +Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv +O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq +dAv8JggJICUvax2T9va5 gsg-keypair +---- You just append them to your `authorized_keys` file: - $ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys - $ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys - $ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys +[source,shell] +---- +$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys +$ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys +$ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys +---- Now, you can set up an empty repository for them by running `git init` with the `--bare` option, which initializes the repository without a working directory: - $ cd /opt/git - $ mkdir project.git - $ cd project.git - $ git --bare init +[source,shell] +---- +$ cd /opt/git +$ mkdir project.git +$ cd project.git +$ git --bare init +---- Then, John, Josie, or Jessica can push the first version of their project into that repository by adding it as a remote and pushing up a branch. Note that someone must shell onto the machine and create a bare repository every time you want to add a project. Let’s use `gitserver` as the hostname of the server on which you’ve set up your 'git' user and repository. If you’re running it internally, and you set up DNS for `gitserver` to point to that server, then you can use the commands pretty much as is: - # on Johns computer - $ cd myproject - $ git init - $ git add . - $ git commit -m 'initial commit' - $ git remote add origin git@gitserver:/opt/git/project.git - $ git push origin master +[source,shell] +---- +# on Johns computer +$ cd myproject +$ git init +$ git add . +$ git commit -m 'initial commit' +$ git remote add origin git@gitserver:/opt/git/project.git +$ git push origin master +---- At this point, the others can clone it down and push changes back up just as easily: - $ git clone git@gitserver:/opt/git/project.git - $ vim README - $ git commit -am 'fix for the README file' - $ git push origin master +[source,shell] +---- +$ git clone git@gitserver:/opt/git/project.git +$ vim README +$ git commit -am 'fix for the README file' +$ git push origin master +---- With this method, you can quickly get a read/write Git server up and running for a handful of developers. @@ -373,23 +437,35 @@ If you set this as your 'git' user’s login shell, then the 'git' user can’t To use this, specify `git-shell` instead of bash or csh for your user’s login shell. To do so, you’ll likely have to edit your `/etc/passwd` file: - $ sudo vim /etc/passwd +[source,shell] +---- +$ sudo vim /etc/passwd +---- At the bottom, you should find a line that looks something like this: - git:x:1000:1000::/home/git:/bin/sh +[source,shell] +---- +git:x:1000:1000::/home/git:/bin/sh +---- Change `/bin/sh` to `/usr/bin/git-shell` (or run `which git-shell` to see where it’s installed). The line should look something like this: - git:x:1000:1000::/home/git:/usr/bin/git-shell +[source,shell] +---- +git:x:1000:1000::/home/git:/usr/bin/git-shell +---- Now, the 'git' user can only use the SSH connection to push and pull Git repositories and can’t shell onto the machine. If you try, you’ll see a login rejection like this: - $ ssh git@gitserver - fatal: What do you think I am? A shell? - Connection to gitserver closed. +[source,shell] +---- +$ ssh git@gitserver +fatal: What do you think I am? A shell? +Connection to gitserver closed. +---- === Public Access @@ -404,40 +480,53 @@ Again, you can use any web server for this; but as an example, we’ll demonstra First you need to enable the hook: - $ cd project.git - $ mv hooks/post-update.sample hooks/post-update - $ chmod a+x hooks/post-update - -If you’re using a version of Git earlier than 1.6, the `mv` command isn’t necessary – Git started naming the hooks examples with the .sample postfix only recently. +[source,shell] +---- +$ cd project.git +$ mv hooks/post-update.sample hooks/post-update +$ chmod a+x hooks/post-update +---- What does this `post-update` hook do? It looks basically like this: - $ cat .git/hooks/post-update - #!/bin/sh - exec git-update-server-info +[source,shell] +---- +$ cat .git/hooks/post-update +#!/bin/sh +exec git-update-server-info +---- This means that when you push to the server via SSH, Git will run this command to update the files needed for HTTP fetching. Next, you need to add a VirtualHost entry to your Apache configuration with the document root as the root directory of your Git projects. Here, we’re assuming that you have wildcard DNS set up to send `*.gitserver` to whatever box you’re using to run all this: - - ServerName git.gitserver - DocumentRoot /opt/git - - Order allow, deny - allow from all - - +[source,shell] +---- + + ServerName git.gitserver + DocumentRoot /opt/git + + Order allow, deny + allow from all + + +---- You’ll also need to set the Unix user group of the `/opt/git` directories to `www-data` so your web server can read-access the repositories, because the Apache instance running the CGI script will (by default) be running as that user: - $ chgrp -R www-data /opt/git +[source,shell] +---- +$ chgrp -R www-data /opt/git +---- When you restart Apache, you should be able to clone your repositories under that directory by specifying the URL for your project: - $ git clone http://git.gitserver/project.git +[source,shell] +---- +$ git clone http://git.gitserver/project.git +---- This way, you can set up HTTP-based read access to any of your projects for a fair number of users in a few minutes. Another simple option for public unauthenticated access is to start a Git daemon, although that requires you to daemonize the process - we’ll cover this option in the next section, if you prefer that route. @@ -457,42 +546,54 @@ On Linux machines, `lighttpd` is often installed, so you may be able to get it t If you’re running a Mac, Leopard comes preinstalled with Ruby, so `webrick` may be your best bet. To start `instaweb` with a non-lighttpd handler, you can run it with the `--httpd` option. - $ git instaweb --httpd=webrick - [2009-02-21 10:02:21] INFO WEBrick 1.3.1 - [2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0] +[source,shell] +---- +$ git instaweb --httpd=webrick +[2009-02-21 10:02:21] INFO WEBrick 1.3.1 +[2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0] +---- That starts up an HTTPD server on port 1234 and then automatically starts a web browser that opens on that page. It’s pretty easy on your part. When you’re done and want to shut down the server, you can run the same command with the `--stop` option: - $ git instaweb --httpd=webrick --stop +[source,shell] +---- +$ git instaweb --httpd=webrick --stop +---- If you want to run the web interface on a server all the time for your team or for an open source project you’re hosting, you’ll need to set up the CGI script to be served by your normal web server. Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `yum`, so you may want to try that first. We’ll walk though installing GitWeb manually very quickly. First, you need to get the Git source code, which GitWeb comes with, and generate the custom CGI script: - $ git clone git://git.kernel.org/pub/scm/git/git.git - $ cd git/ - $ make GITWEB_PROJECTROOT="/opt/git" \ - prefix=/usr gitweb/gitweb.cgi - $ sudo cp -Rf gitweb /var/www/ +[source,shell] +---- +$ git clone git://git.kernel.org/pub/scm/git/git.git +$ cd git/ +$ make GITWEB_PROJECTROOT="/opt/git" \ + prefix=/usr gitweb/gitweb.cgi +$ sudo cp -Rf gitweb /var/www/ +---- Notice that you have to tell the command where to find your Git repositories with the `GITWEB_PROJECTROOT` variable. Now, you need to make Apache use CGI for that script, for which you can add a VirtualHost: - - ServerName gitserver - DocumentRoot /var/www/gitweb - - Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch - AllowOverride All - order allow,deny - Allow from all - AddHandler cgi-script cgi - DirectoryIndex gitweb.cgi - - +[source,shell] +---- + + ServerName gitserver + DocumentRoot /var/www/gitweb + + Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch + AllowOverride All + order allow,deny + Allow from all + AddHandler cgi-script cgi + DirectoryIndex gitweb.cgi + + +---- Again, GitWeb can be served with any CGI capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. At this point, you should be able to visit `http://gitserver/` to view your repositories online, and you can use `http://git.gitserver` to clone and fetch your repositories over HTTP. @@ -510,7 +611,10 @@ If the server you’re running it on is inside your firewall, you might use it f In any case, the Git protocol is relatively easy to set up. Basically, you need to run this command in a daemonized manner: - git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ +[source,shell] +---- +git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ +---- `--reuseaddr` allows the server to restart without waiting for old connections to time out, the `--base-path` option allows people to clone projects without specifying the entire path, and the path at the end tells the Git daemon where to look for repositories to export. If you’re running a firewall, you’ll also need to punch a hole in it at port 9418 on the box you’re setting this up on. @@ -519,18 +623,24 @@ You can daemonize this process a number of ways, depending on the operating syst On an Ubuntu machine, you use an Upstart script. So, in the following file - /etc/event.d/local-git-daemon +[source,shell] +---- +/etc/event.d/local-git-daemon +---- you put this script: - start on startup - stop on shutdown - exec /usr/bin/git daemon \ - --user=git --group=git \ - --reuseaddr \ - --base-path=/opt/git/ \ - /opt/git/ - respawn +[source,shell] +---- +start on startup +stop on shutdown +exec /usr/bin/git daemon \ + --user=git --group=git \ + --reuseaddr \ + --base-path=/opt/git/ \ + /opt/git/ +respawn +---- For security reasons, it is strongly encouraged to have this daemon run as a user with read-only permissions to the repositories – you can easily do this by creating a new user 'git-ro' and running the daemon as them. For the sake of simplicity we’ll simply run it as the same 'git' user that Gitosis is running as. @@ -538,7 +648,10 @@ For the sake of simplicity we’ll simply run it as the same 'git' user that Git When you restart your machine, your Git daemon will start automatically and respawn if it goes down. To get it running without having to reboot, you can run this: - initctl start local-git-daemon +[source,shell] +---- +initctl start local-git-daemon +---- On other systems, you may want to use `xinetd`, a script in your `sysvinit` system, or something else – as long as you get that command daemonized and watched somehow. @@ -546,32 +659,44 @@ Next, you have to tell your Gitosis server which repositories to allow unauthent If you add a section for each repository, you can specify the ones from which you want your Git daemon to allow reading. If you want to allow Git protocol access for your iphone project, you add this to the end of the `gitosis.conf` file: - [repo iphone_project] - daemon = yes +[source,shell] +---- +[repo iphone_project] +daemon = yes +---- When that is committed and pushed up, your running daemon should start serving requests for the project to anyone who has access to port 9418 on your server. If you decide not to use Gitosis, but you want to set up a Git daemon, you’ll have to run this on each project you want the Git daemon to serve: - $ cd /path/to/project.git - $ touch git-daemon-export-ok +[source,shell] +---- +$ cd /path/to/project.git +$ touch git-daemon-export-ok +---- The presence of that file tells Git that it’s OK to serve this project without authentication. Gitosis can also control which projects GitWeb shows. First, you need to add something like the following to the `/etc/gitweb.conf` file: - $projects_list = "/home/git/gitosis/projects.list"; - $projectroot = "/home/git/repositories"; - $export_ok = "git-daemon-export-ok"; - @git_base_url_list = ('git://gitserver'); +[source,shell] +---- +$projects_list = "/home/git/gitosis/projects.list"; +$projectroot = "/home/git/repositories"; +$export_ok = "git-daemon-export-ok"; +@git_base_url_list = ('git://gitserver'); +---- You can control which projects GitWeb lets users browse by adding or removing a `gitweb` setting in the Gitosis configuration file. For instance, if you want the iphone project to show up on GitWeb, you make the `repo` setting look like this: - [repo iphone_project] - daemon = yes - gitweb = yes +[source,shell] +---- +[repo iphone_project] +daemon = yes +gitweb = yes +---- Now, if you commit and push the project, GitWeb will automatically start showing your iphone project. @@ -684,11 +809,17 @@ Each project is accessible over HTTPS or SSH, either of which can be used to con The URLs are visible at the top of the project's home page. For an existing local repository, this command will create a remote named `gitlab` to the hosted location: - git remote add gitlab https://server/namespace/project.git +[source,shell] +---- +$ git remote add gitlab https://server/namespace/project.git +---- If you don't have a local copy of the repository, you can simply do this: - git clone https://server/namespace/project.git +[source,shell] +---- +$ git clone https://server/namespace/project.git +---- The web UI provides access to several useful views of the repository itself. Each project's home page shows recent activity, and links along the top will lead you to views of the project's files and commit log. @@ -715,6 +846,8 @@ One benefit to GitLab is that, once the server is set up and running, you'll rar === Gerrit +TODO: Gerrit + === Other Hosting Options If you don’t want to go through all of the work involved in setting up your own Git server, you have several options for hosting your Git projects on an external dedicated hosting site. @@ -722,15 +855,8 @@ Doing so offers a number of advantages: a hosting site is generally quick to set Even if you set up and run your own server internally, you may still want to use a public hosting site for your open source code – it’s generally easier for the open source community to find and help you with. These days, you have a huge number of hosting options to choose from, each with different advantages and disadvantages. -To see an up-to-date list, check out the GitHosting page on the main Git wiki: - - http://git.or.cz/gitwiki/GitHosting - -Because we can’t cover all of them, and because I happen to work at one of them, we’ll use this section to walk through setting up an account and creating a new project at GitHub. -This will give you an idea of what is involved. +To see an up-to-date list, check out the GitHosting page on the main Git wiki at https://git.wiki.kernel.org/index.php/GitHosting[] -GitHub is by far the largest open source Git hosting site and it’s also one of the very few that offers both public and private hosting options so you can keep your open source and private commercial code in the same place. -In fact, we used GitHub to privately collaborate on this book. === Summary From c53ffd0e7b2c1690f8b2ff959c14284f546d1904 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 12:11:22 -0700 Subject: [PATCH 04/13] some tweaks to git on the server --- book/04-git-server/1-git-server.asc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index fc3df6f05..b944143f8 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -212,6 +212,14 @@ Behind big corporate firewalls, this obscure port is commonly blocked. === Getting Git on a Server +Now we'll cover setting up a Git service running these protocols on your own server. + +[NOTE] +==== +Here we'll be demonstrating the commands and steps needed to do basic installations on a Linux based server, though it's also possible to run these services on Mac or Windows servers too. +Actually setting up a production server within your infrastructure will certainly entail differences in security measures or operating system tools, but hopefully this will give you the general idea of what's involved. +==== + In order to initially set up any Git server, you have to export an existing repository into a new bare repository – a repository that doesn’t contain a working directory. This is generally straightforward to do. In order to clone your repository to create a new bare repository, you run the clone command with the `--bare` option. @@ -224,9 +232,6 @@ Cloning into bare repository 'my_project.git'... done. ---- -The output for this command is a little confusing. -Since `clone` is basically a `git init` then a `git fetch`, we see some output from the `git init` part, which creates an empty directory. -The actual object transfer gives no output, but it does happen. You should now have a copy of the Git directory data in your `my_project.git` directory. This is roughly equivalent to something like @@ -243,7 +248,7 @@ It takes the Git repository by itself, without a working directory, and creates Now that you have a bare copy of your repository, all you need to do is put it on a server and set up your protocols. Let’s say you’ve set up a server called `git.example.com` that you have SSH access to, and you want to store all your Git repositories under the `/opt/git` directory. -You can set up your new repository by copying your bare repository over: +Assuming that `/opt/git` exists on that server, you can set up your new repository by copying your bare repository over: [source,shell] ---- @@ -258,6 +263,7 @@ $ git clone user@git.example.com:/opt/git/my_project.git ---- If a user SSHs into a server and has write access to the `/opt/git/my_project.git` directory, they will also automatically have push access. + Git will automatically add group write permissions to a repository properly if you run the `git init` command with the `--shared` option. [source,shell] @@ -857,6 +863,7 @@ Even if you set up and run your own server internally, you may still want to use These days, you have a huge number of hosting options to choose from, each with different advantages and disadvantages. To see an up-to-date list, check out the GitHosting page on the main Git wiki at https://git.wiki.kernel.org/index.php/GitHosting[] +We'll cover using GitHub in detail in <<_github>>, as it is the largest Git host out there and you may need to interact with projects hosted on it in any case, but there are dozens more to choose from should you not want to set up your own Git server. === Summary From 60b66c8a06e6194fa07a35d32cdbb2840a5530fb Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 12:43:02 -0700 Subject: [PATCH 05/13] a couple of small changes plus git-server updates --- TODO.asc | 6 +++-- book/04-git-server/1-git-server.asc | 34 +++++++++++++++++++---------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/TODO.asc b/TODO.asc index 173d26dc1..46669a4b1 100644 --- a/TODO.asc +++ b/TODO.asc @@ -3,6 +3,9 @@ Until we get these all into issues, I wanted to put in what I had on my TODO list for the second edition. +* add highlighting to HEAD branches in diagrams (ch3) +* Advanced merge tools (diff, log, etc) + == Processes / Procedures * Asciidoc / Git Scribe @@ -34,7 +37,7 @@ Until we get these all into issues, I wanted to put in what I had on my TODO lis * libgit2 - some bindings examples? -* GitHub chapter +* GitHub chapter - flow - api - hub @@ -47,4 +50,3 @@ Until we get these all into issues, I wanted to put in what I had on my TODO lis * gh or hub http://owenou.com/2012/01/13/ten-things-you-didnt-know-git-and-github-could-do.html - diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index b944143f8..081278765 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -287,11 +287,11 @@ However, keep in mind that to collaborate with a couple of people on a private p If you’re a small outfit or are just trying out Git in your organization and have only a few developers, things can be simple for you. One of the most complicated aspects of setting up a Git server is user management. -If you want some repositories to be read-only to certain users and read/write to others, access and permissions can be a bit difficult to arrange. +If you want some repositories to be read-only to certain users and read/write to others, access and permissions can be a bit more difficult to arrange. ===== SSH Access -If you already have a server to which all your developers have SSH access, it’s generally easiest to set up your first repository there, because you have to do almost no work (as we covered in the last section). +If you have a server to which all your developers already have SSH access, it’s generally easiest to set up your first repository there, because you have to do almost no work (as we covered in the last section). If you want more complex access control type permissions on your repositories, you can handle them with the normal filesystem permissions of the operating system your server runs. If you want to place your repositories on a server that doesn’t have accounts for everyone on your team whom you want to have write access, then you must set up SSH access for them. @@ -325,7 +325,7 @@ authorized_keys2 id_dsa known_hosts config id_dsa.pub ---- -You’re looking for a pair of files named something and something.pub, where the something is usually `id_dsa` or `id_rsa`. +You’re looking for a pair of files named something like `id_dsa` or `id_rsa` and a matching file with a `.pub` extension. The `.pub` file is your public key, and the other file is your private key. If you don’t have these files (or you don’t even have a `.ssh` directory), you can create them by running a program called `ssh-keygen`, which is provided with the SSH package on Linux/Mac systems and comes with the MSysGit package on Windows: @@ -333,13 +333,14 @@ If you don’t have these files (or you don’t even have a `.ssh` directory), y ---- $ ssh-keygen Generating public/private rsa key pair. -Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): +Enter file in which to save the key (/home/schacon/.ssh/id_rsa): +Created directory '/home/schacon/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: -Your identification has been saved in /Users/schacon/.ssh/id_rsa. -Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub. +Your identification has been saved in /home/schacon/.ssh/id_rsa. +Your public key has been saved in /home/schacon/.ssh/id_rsa.pub. The key fingerprint is: -43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local +d0:82:24:8e:d7:f1:bb:9b:33:53:96:93:49:da:9b:e3 schacon@mylaptop.local ---- First it confirms where you want to save the key (`.ssh/id_rsa`), and then it asks twice for a passphrase, which you can leave empty if you don’t want to type a password when you use the key. @@ -356,10 +357,10 @@ GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx -NrRFi9wrf+M7Q== schacon@agadorlaptop.local +NrRFi9wrf+M7Q== schacon@mylaptop.local ---- -For a more in-depth tutorial on creating an SSH key on multiple operating systems, see the GitHub guide on SSH keys at `http://github.com/guides/providing-your-ssh-key`. +For a more in-depth tutorial on creating an SSH key on multiple operating systems, see the GitHub guide on SSH keys at https://help.github.com/articles/generating-ssh-keys[]. === Setting Up the Server @@ -407,7 +408,8 @@ Now, you can set up an empty repository for them by running `git init` with the $ cd /opt/git $ mkdir project.git $ cd project.git -$ git --bare init +$ git init --bare +Initialized empty Git repository in /opt/git/project.git/ ---- Then, John, Josie, or Jessica can push the first version of their project into that repository by adding it as a remote and pushing up a branch. @@ -438,7 +440,9 @@ $ git push origin master With this method, you can quickly get a read/write Git server up and running for a handful of developers. -As an extra precaution, you can easily restrict the 'git' user to only doing Git activities with a limited shell tool called `git-shell` that comes with Git. +You should note that currently all these users can also log into the server and get a shell as the ``git'' user. If you want to restrict that, you will have to change the shell to something else in the `passwd` file. + +You can easily restrict the 'git' user to only doing Git activities with a limited shell tool called `git-shell` that comes with Git. If you set this as your 'git' user’s login shell, then the 'git' user can’t have normal shell access to your server. To use this, specify `git-shell` instead of bash or csh for your user’s login shell. To do so, you’ll likely have to edit your `/etc/passwd` file: @@ -469,10 +473,16 @@ If you try, you’ll see a login rejection like this: [source,shell] ---- $ ssh git@gitserver -fatal: What do you think I am? A shell? +fatal: Interactive git shell is not enabled. +hint: ~/git-shell-commands should exist and have read and execute access. Connection to gitserver closed. ---- +Now Git network commands will still work just fine but the users won't be able to get a shell. +As the output states, you can also set up a directory in the ``git'' user's home directory that customizes the `git-shell` command a bit. +For instance, you can restrict the Git commands that the server will accept or you can customize the message that users see if they try to SSH in like that. +Run `git help shell` for more information on customizing the shell. + === Public Access What if you want anonymous read access to your project? From 388475d68d8d2946c5cea867dd2da6e5fe73aff2 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 12:56:38 -0700 Subject: [PATCH 06/13] remove dumb http setup entirely, move git daemon section up before gitweb --- book/04-git-server/1-git-server.asc | 200 ++++++++++------------------ 1 file changed, 68 insertions(+), 132 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 081278765..954df3367 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -481,138 +481,7 @@ Connection to gitserver closed. Now Git network commands will still work just fine but the users won't be able to get a shell. As the output states, you can also set up a directory in the ``git'' user's home directory that customizes the `git-shell` command a bit. For instance, you can restrict the Git commands that the server will accept or you can customize the message that users see if they try to SSH in like that. -Run `git help shell` for more information on customizing the shell. - -=== Public Access - -What if you want anonymous read access to your project? -Perhaps instead of hosting an internal private project, you want to host an open source project. -Or maybe you have a bunch of automated build servers or continuous integration servers that change a lot, and you don’t want to have to generate SSH keys all the time – you just want to add simple anonymous read access. - -Probably the simplest way for smaller setups is to run a static web server with its document root where your Git repositories are, and then enable that `post-update` hook we mentioned in the first section of this chapter. -Let’s work from the previous example. -Say you have your repositories in the `/opt/git` directory, and an Apache server is running on your machine. -Again, you can use any web server for this; but as an example, we’ll demonstrate some basic Apache configurations that should give you an idea of what you might need. - -First you need to enable the hook: - -[source,shell] ----- -$ cd project.git -$ mv hooks/post-update.sample hooks/post-update -$ chmod a+x hooks/post-update ----- - -What does this `post-update` hook do? -It looks basically like this: - -[source,shell] ----- -$ cat .git/hooks/post-update -#!/bin/sh -exec git-update-server-info ----- - -This means that when you push to the server via SSH, Git will run this command to update the files needed for HTTP fetching. - -Next, you need to add a VirtualHost entry to your Apache configuration with the document root as the root directory of your Git projects. -Here, we’re assuming that you have wildcard DNS set up to send `*.gitserver` to whatever box you’re using to run all this: - -[source,shell] ----- - - ServerName git.gitserver - DocumentRoot /opt/git - - Order allow, deny - allow from all - - ----- - -You’ll also need to set the Unix user group of the `/opt/git` directories to `www-data` so your web server can read-access the repositories, because the Apache instance running the CGI script will (by default) be running as that user: - -[source,shell] ----- -$ chgrp -R www-data /opt/git ----- - -When you restart Apache, you should be able to clone your repositories under that directory by specifying the URL for your project: - -[source,shell] ----- -$ git clone http://git.gitserver/project.git ----- - -This way, you can set up HTTP-based read access to any of your projects for a fair number of users in a few minutes. -Another simple option for public unauthenticated access is to start a Git daemon, although that requires you to daemonize the process - we’ll cover this option in the next section, if you prefer that route. - -=== GitWeb - -Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. -Git comes with a CGI script called GitWeb that is commonly used for this. -You can see GitWeb in use at sites like `http://git.kernel.org` (see <>). - -[[gitweb]] -.The GitWeb web-based user interface. -image::images/18333fig0401-tn.png[The GitWeb web-based user interface.] - -If you want to check out what GitWeb would look like for your project, Git comes with a command to fire up a temporary instance if you have a lightweight server on your system like `lighttpd` or `webrick`. -On Linux machines, `lighttpd` is often installed, so you may be able to get it to run by typing `git instaweb` in your project directory. -If you’re running a Mac, Leopard comes preinstalled with Ruby, so `webrick` may be your best bet. -To start `instaweb` with a non-lighttpd handler, you can run it with the `--httpd` option. - -[source,shell] ----- -$ git instaweb --httpd=webrick -[2009-02-21 10:02:21] INFO WEBrick 1.3.1 -[2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0] ----- - -That starts up an HTTPD server on port 1234 and then automatically starts a web browser that opens on that page. -It’s pretty easy on your part. -When you’re done and want to shut down the server, you can run the same command with the `--stop` option: - -[source,shell] ----- -$ git instaweb --httpd=webrick --stop ----- - -If you want to run the web interface on a server all the time for your team or for an open source project you’re hosting, you’ll need to set up the CGI script to be served by your normal web server. -Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `yum`, so you may want to try that first. -We’ll walk though installing GitWeb manually very quickly. -First, you need to get the Git source code, which GitWeb comes with, and generate the custom CGI script: - -[source,shell] ----- -$ git clone git://git.kernel.org/pub/scm/git/git.git -$ cd git/ -$ make GITWEB_PROJECTROOT="/opt/git" \ - prefix=/usr gitweb/gitweb.cgi -$ sudo cp -Rf gitweb /var/www/ ----- - -Notice that you have to tell the command where to find your Git repositories with the `GITWEB_PROJECTROOT` variable. -Now, you need to make Apache use CGI for that script, for which you can add a VirtualHost: - -[source,shell] ----- - - ServerName gitserver - DocumentRoot /var/www/gitweb - - Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch - AllowOverride All - order allow,deny - Allow from all - AddHandler cgi-script cgi - DirectoryIndex gitweb.cgi - - ----- - -Again, GitWeb can be served with any CGI capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. -At this point, you should be able to visit `http://gitserver/` to view your repositories online, and you can use `http://git.gitserver` to clone and fetch your repositories over HTTP. +Run `git help shell` for more information on customizing the shell. === Git Daemon @@ -716,6 +585,73 @@ gitweb = yes Now, if you commit and push the project, GitWeb will automatically start showing your iphone project. +=== GitWeb + +Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. +Git comes with a CGI script called GitWeb that is commonly used for this. +You can see GitWeb in use at sites like `http://git.kernel.org` (see <>). + +[[gitweb]] +.The GitWeb web-based user interface. +image::images/18333fig0401-tn.png[The GitWeb web-based user interface.] + +If you want to check out what GitWeb would look like for your project, Git comes with a command to fire up a temporary instance if you have a lightweight server on your system like `lighttpd` or `webrick`. +On Linux machines, `lighttpd` is often installed, so you may be able to get it to run by typing `git instaweb` in your project directory. +If you’re running a Mac, Leopard comes preinstalled with Ruby, so `webrick` may be your best bet. +To start `instaweb` with a non-lighttpd handler, you can run it with the `--httpd` option. + +[source,shell] +---- +$ git instaweb --httpd=webrick +[2009-02-21 10:02:21] INFO WEBrick 1.3.1 +[2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0] +---- + +That starts up an HTTPD server on port 1234 and then automatically starts a web browser that opens on that page. +It’s pretty easy on your part. +When you’re done and want to shut down the server, you can run the same command with the `--stop` option: + +[source,shell] +---- +$ git instaweb --httpd=webrick --stop +---- + +If you want to run the web interface on a server all the time for your team or for an open source project you’re hosting, you’ll need to set up the CGI script to be served by your normal web server. +Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `yum`, so you may want to try that first. +We’ll walk though installing GitWeb manually very quickly. +First, you need to get the Git source code, which GitWeb comes with, and generate the custom CGI script: + +[source,shell] +---- +$ git clone git://git.kernel.org/pub/scm/git/git.git +$ cd git/ +$ make GITWEB_PROJECTROOT="/opt/git" \ + prefix=/usr gitweb/gitweb.cgi +$ sudo cp -Rf gitweb /var/www/ +---- + +Notice that you have to tell the command where to find your Git repositories with the `GITWEB_PROJECTROOT` variable. +Now, you need to make Apache use CGI for that script, for which you can add a VirtualHost: + +[source,shell] +---- + + ServerName gitserver + DocumentRoot /var/www/gitweb + + Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch + AllowOverride All + order allow,deny + Allow from all + AddHandler cgi-script cgi + DirectoryIndex gitweb.cgi + + +---- + +Again, GitWeb can be served with any CGI capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. +At this point, you should be able to visit `http://gitserver/` to view your repositories online, and you can use `http://git.gitserver` to clone and fetch your repositories over HTTP. + === GitLab From efc44d7cd71603de0aad3c88a1055bb4ca538445 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 16:38:21 -0700 Subject: [PATCH 07/13] some updates to git-daemon examples and remove gitosis sections --- book/04-git-server/1-git-server.asc | 44 ++--------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 954df3367..03b7294f5 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -485,11 +485,8 @@ Run `git help shell` for more information on customizing the shell. === Git Daemon -For public, unauthenticated read access to your projects, you’ll want to move past the HTTP protocol and start using the Git protocol. -The main reason is speed. -The Git protocol is far more efficient and thus faster than the HTTP protocol, so using it will save your users time. +Next we'll set up a daemon serving repositories over the ``Git'' protocol. This is common choice for fast, unauthenticated access to your Git data. Remember that since it's not an authenticated service, anything you serve over this protocol is public within it's network. -Again, this is for unauthenticated read-only access. If you’re running this on a server outside your firewall, it should only be used for projects that are publicly visible to the world. If the server you’re running it on is inside your firewall, you might use it for projects that a large number of people or computers (continuous integration or build servers) have read-only access to, when you don’t want to have to add an SSH key for each. @@ -505,7 +502,7 @@ git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ If you’re running a firewall, you’ll also need to punch a hole in it at port 9418 on the box you’re setting this up on. You can daemonize this process a number of ways, depending on the operating system you’re running. -On an Ubuntu machine, you use an Upstart script. +On an Ubuntu machine, you can use an Upstart script. So, in the following file [source,shell] @@ -540,19 +537,7 @@ initctl start local-git-daemon On other systems, you may want to use `xinetd`, a script in your `sysvinit` system, or something else – as long as you get that command daemonized and watched somehow. -Next, you have to tell your Gitosis server which repositories to allow unauthenticated Git server-based access to. -If you add a section for each repository, you can specify the ones from which you want your Git daemon to allow reading. -If you want to allow Git protocol access for your iphone project, you add this to the end of the `gitosis.conf` file: - -[source,shell] ----- -[repo iphone_project] -daemon = yes ----- - -When that is committed and pushed up, your running daemon should start serving requests for the project to anyone who has access to port 9418 on your server. - -If you decide not to use Gitosis, but you want to set up a Git daemon, you’ll have to run this on each project you want the Git daemon to serve: +Next, you have to tell Git which repositories to allow unauthenticated Git server-based access to. You can do this in each repository by creating a file name `git-daemon-export-ok`. [source,shell] ---- @@ -562,29 +547,6 @@ $ touch git-daemon-export-ok The presence of that file tells Git that it’s OK to serve this project without authentication. -Gitosis can also control which projects GitWeb shows. -First, you need to add something like the following to the `/etc/gitweb.conf` file: - -[source,shell] ----- -$projects_list = "/home/git/gitosis/projects.list"; -$projectroot = "/home/git/repositories"; -$export_ok = "git-daemon-export-ok"; -@git_base_url_list = ('git://gitserver'); ----- - -You can control which projects GitWeb lets users browse by adding or removing a `gitweb` setting in the Gitosis configuration file. -For instance, if you want the iphone project to show up on GitWeb, you make the `repo` setting look like this: - -[source,shell] ----- -[repo iphone_project] -daemon = yes -gitweb = yes ----- - -Now, if you commit and push the project, GitWeb will automatically start showing your iphone project. - === GitWeb Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. From 5d1b95376e0aef43b6323c5018d7e563c8df447c Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 17:12:13 -0700 Subject: [PATCH 08/13] final first round edits - fixed up some gitweb info - removed the non-local options of gitlab, there is no reason to mention commercial offerings - this chapter is for running your own server --- book/04-git-server/1-git-server.asc | 37 +++++++++++------------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 03b7294f5..21a248a81 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -550,8 +550,7 @@ The presence of that file tells Git that it’s OK to serve this project without === GitWeb Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. -Git comes with a CGI script called GitWeb that is commonly used for this. -You can see GitWeb in use at sites like `http://git.kernel.org` (see <>). +Git comes with a CGI script called GitWeb that is sometimes used for this. [[gitweb]] .The GitWeb web-based user interface. @@ -587,8 +586,12 @@ First, you need to get the Git source code, which GitWeb comes with, and generat ---- $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ -$ make GITWEB_PROJECTROOT="/opt/git" \ - prefix=/usr gitweb/gitweb.cgi +$ make GITWEB_PROJECTROOT="/opt/git" prefix=/usr gitweb + SUBDIR gitweb + SUBDIR ../ +make[2]: `GIT-VERSION-FILE' is up to date. + GEN gitweb.cgi + GEN static/gitweb.js $ sudo cp -Rf gitweb /var/www/ ---- @@ -611,27 +614,15 @@ Now, you need to make Apache use CGI for that script, for which you can add a Vi ---- -Again, GitWeb can be served with any CGI capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. -At this point, you should be able to visit `http://gitserver/` to view your repositories online, and you can use `http://git.gitserver` to clone and fetch your repositories over HTTP. - +Again, GitWeb can be served with any CGI or Perl capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. +At this point, you should be able to visit `http://gitserver/` to view your repositories online. === GitLab -If you're working on a team, often you need more than source code hosting. -GitLab is one package that offers project structure, issue tracking, chat, wikis, and collaboration with unprivileged users, in addition to ``just'' git hosting. - -==== Flavors - -GitLab is a fully open-source project (the project page can be found at http://www.gitlab.org[]), which is developed and supported by a for-profit company (found at http://www.gitlab.com[]). -There are several options for obtaining and using GitLab: - -1. The Community Edition is the basic product, and is offered free of charge. - You install the software on your machine, and you're responsible for configuring and updating it. -2. The Enterprise Edition extends the Community Edition with some extra features, and is available through a subscription plan. - Your subscription fees pay for installation and configuration support, ongoing technical support, and continued GitLab development. -3. GitLab Cloud is an installation of the Community Edition running on GitLab's servers. - There's no charge for the service, and very few limits on how you use it. - This is a great way to take GitLab for a spin before expending effort configuring your own server. +GitWeb is pretty simplistic though. +If you're looking for a more modern, fully featured Git server, there are some several open source solutions out there that you can install instead. +As GitLab is one of the more popular ones, we'll cover installing and using it as an example. +This is a bit more complex than the GitWeb option and likely requires more maintainance, but it is a much more fully featured option. ==== Installation @@ -762,7 +753,7 @@ One benefit to GitLab is that, once the server is set up and running, you'll rar TODO: Gerrit -=== Other Hosting Options +=== Third Party Hosted Options If you don’t want to go through all of the work involved in setting up your own Git server, you have several options for hosting your Git projects on an external dedicated hosting site. Doing so offers a number of advantages: a hosting site is generally quick to set up and easy to start projects on, and no server maintenance or monitoring is involved. From d867f3e90e012452a7fbd1b5fd81bc441762e3c3 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Wed, 11 Jun 2014 17:23:57 -0700 Subject: [PATCH 09/13] pasted directly from the blog post, but it gives me something to work with --- book/04-git-server/1-git-server.asc | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 21a248a81..d7774f3a8 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -547,6 +547,34 @@ $ touch git-daemon-export-ok The presence of that file tells Git that it’s OK to serve this project without authentication. +=== Smart HTTP + +Smart-HTTP is basically just enabling the new CGI script that is provided with Git called `git-http-backend` on the server. This CGI will read the path and headers sent by the revamped git fetch and git push binaries who have learned to communicate in a specific way with a smart server. If the CGI sees that the client is smart, it will communicate smartly with it, otherwise it will simply fall back to the dumb behavior (so it is backward compatible for reads with older clients). + +To set it up, it's best to walk through the instructions on the `git-http-backend` documentation page. Basically, you have to install Git v1.6.6 or higher on a server with an Apache 2.x webserver (it has to be Apache, currently - other CGI servers don't work, last I checked). Then you add something similar to this to your http.conf file: + +[source,shell] +---- +SetEnv GIT_PROJECT_ROOT /var/www/git +SetEnv GIT_HTTP_EXPORT_ALL +ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ +---- + +Then you'll want to make writes be authenticated somehow, possibly with an Auth block like this: + +[source,shell] +---- + + AuthType Basic + AuthName "Git Access" + Require group committers + ... + +---- + +That is all that is really required to get this running. Now you have a smart http-based Git server that can do anonymous reads and authenticated writes with clients that have upgraded to 1.6.6 and above. How awesome is that? The documentation goes over more complex examples, like making it work with GitWeb and accelerating the dumb fallback reads, if you're interested. + + === GitWeb Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. @@ -617,6 +645,7 @@ Now, you need to make Apache use CGI for that script, for which you can add a Vi Again, GitWeb can be served with any CGI or Perl capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. At this point, you should be able to visit `http://gitserver/` to view your repositories online. + === GitLab GitWeb is pretty simplistic though. From f48a1cd3dd67559e7be36f64324099489060fe67 Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Wed, 11 Jun 2014 19:54:16 -0700 Subject: [PATCH 10/13] Fix a link --- book/04-git-server/1-git-server.asc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index d7774f3a8..b9011da4c 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -94,7 +94,7 @@ The ``smart'' HTTP protocol operates very similarly to the SSH or Git protocols It has probably become the most popular way to use Git now, since it can be set up to both serve anonymously like the `git://` protocol, and can also be pushed over with authentication like the SSH protocol. Instead of having to set up different URLs for these things, you can now use a single URL for both. If you try to push and the repository requires authentication (which it normally should), the server can prompt for a username and password. The same goes for read access. -In fact, for services like GitHub, the URL you use to view the repository online (for example, ``https://github.com/schacon/simplegit'') is the same URL you can use to clone and, if you have access, push over. +In fact, for services like GitHub, the URL you use to view the repository online (for example, ``https://github.com/schacon/simplegit[]'') is the same URL you can use to clone and, if you have access, push over. ===== Dumb HTTP From 4895514b2562c26257a2c375abf7133e4e6ccd02 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Thu, 12 Jun 2014 10:50:49 -0700 Subject: [PATCH 11/13] slightly better Smart HTTP description --- book/04-git-server/1-git-server.asc | 54 ++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index b9011da4c..14facf7ad 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -549,30 +549,66 @@ The presence of that file tells Git that it’s OK to serve this project without === Smart HTTP -Smart-HTTP is basically just enabling the new CGI script that is provided with Git called `git-http-backend` on the server. This CGI will read the path and headers sent by the revamped git fetch and git push binaries who have learned to communicate in a specific way with a smart server. If the CGI sees that the client is smart, it will communicate smartly with it, otherwise it will simply fall back to the dumb behavior (so it is backward compatible for reads with older clients). +We now have authenticated access though SSH and unauthenticated access through `git://`, but there is also a protocol that can do both at the same time. +Setting up Smart HTTP is basically just enabling a CGI script that is provided with Git called `git-http-backend` on the server.((git, http-backend)) +This CGI will read the path and headers sent by a `git fetch` or `git push` to an HTTP URL and determine if the client can communicate over HTTP (which is true for any client since version 1.6.6). +If the CGI sees that the client is smart, it will communicate smartly with it, otherwise it will fall back to the dumb behavior (so it is backward compatible for reads with older clients). -To set it up, it's best to walk through the instructions on the `git-http-backend` documentation page. Basically, you have to install Git v1.6.6 or higher on a server with an Apache 2.x webserver (it has to be Apache, currently - other CGI servers don't work, last I checked). Then you add something similar to this to your http.conf file: +Let's walk though a very basic setup. We'll set this up with Apache as the CGI server. If you don't have Apache setup, you can do so on a Linux box with something like this: [source,shell] ---- -SetEnv GIT_PROJECT_ROOT /var/www/git +$ sudo apt-get install apache2 apache2-utils +$ a2enmod cgi alias env +---- + +This also enables the `mod_cgi`, `mod_alias`, and `mod_env` modules, which are all needed for this to work properly. + +Next we need to add some things to the Apache configuration to run the `git http-backend` as the handler for anything coming into the `/git` path of your web server. + +[source,shell] +---- +SetEnv GIT_PROJECT_ROOT /opt/git SetEnv GIT_HTTP_EXPORT_ALL ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/ ---- -Then you'll want to make writes be authenticated somehow, possibly with an Auth block like this: +If you leave out `GIT_HTTP_EXPORT_ALL` environment variable, then Git will only serve to unauthenticated clients the repositories with the `git-daemon-export-ok` file in them, just like the Git daemon did. + +Then you'll have to tell Apache to allow requests to that path with something like this: + +[source,shell] +---- + + Options ExecCGI Indexes + Order allow,deny + Allow from all + Require all granted + +---- + +Finally you'll want to make writes be authenticated somehow, possibly with an Auth block like this: [source,shell] ---- - AuthType Basic - AuthName "Git Access" - Require group committers - ... + AuthType Basic + AuthName "Git Access" + AuthUserFile /opt/git/.htpasswd + Require valid-user ---- -That is all that is really required to get this running. Now you have a smart http-based Git server that can do anonymous reads and authenticated writes with clients that have upgraded to 1.6.6 and above. How awesome is that? The documentation goes over more complex examples, like making it work with GitWeb and accelerating the dumb fallback reads, if you're interested. +That will require you to create a `.htaccess` file containing the passwords of all the valid users. Here is an example of adding a ``schacon'' user to the file: + +[source,shell] +---- +$ htdigest -c /opt/git/.htpasswd "Git Access" schacon +---- + +There are tons of ways to have Apache authenticate users, you'll have to choose and implement one of them. This is just the simplest example we could come up with. You'll also almost certainly want to set this up over SSL so all this data is encrypted. + +We don't want to go too far down the rabbit hole of Apache configuration specifics, since you could well be using a different server or have different authenication needs. The idea is that Git comes with a CGI called `git http-backend` that when invoked will do all the negotiation to send and receive data over HTTP. It does not implement any authentication itself, but that can easily be controlled at the layer of the web server that invokes it. === GitWeb From 19a52470bd1be5e851a5349fc8c7350ac567f747 Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Thu, 12 Jun 2014 11:02:33 -0700 Subject: [PATCH 12/13] some more pointing elsewhere --- book/04-git-server/1-git-server.asc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 14facf7ad..12434383f 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -608,7 +608,12 @@ $ htdigest -c /opt/git/.htpasswd "Git Access" schacon There are tons of ways to have Apache authenticate users, you'll have to choose and implement one of them. This is just the simplest example we could come up with. You'll also almost certainly want to set this up over SSL so all this data is encrypted. -We don't want to go too far down the rabbit hole of Apache configuration specifics, since you could well be using a different server or have different authenication needs. The idea is that Git comes with a CGI called `git http-backend` that when invoked will do all the negotiation to send and receive data over HTTP. It does not implement any authentication itself, but that can easily be controlled at the layer of the web server that invokes it. +We don't want to go too far down the rabbit hole of Apache configuration specifics, since you could well be using a different server or have different authenication needs. The idea is that Git comes with a CGI called `git http-backend` that when invoked will do all the negotiation to send and receive data over HTTP. It does not implement any authentication itself, but that can easily be controlled at the layer of the web server that invokes it. You can do this with nearly any CGI-capable web server, so go with the one that you know best. + +[NOTE] +==== +For more information on configuring authentication in Apache, check out the Apache docs here: http://httpd.apache.org/docs/current/howto/auth.html[] +==== === GitWeb From b0f3bb3514f86546907aa0cf58c126d994ff3f1b Mon Sep 17 00:00:00 2001 From: Scott Chacon Date: Thu, 12 Jun 2014 11:52:17 -0700 Subject: [PATCH 13/13] remove gerrit section --- book/04-git-server/1-git-server.asc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/book/04-git-server/1-git-server.asc b/book/04-git-server/1-git-server.asc index 12434383f..d2b3ff0fa 100644 --- a/book/04-git-server/1-git-server.asc +++ b/book/04-git-server/1-git-server.asc @@ -819,10 +819,6 @@ This section has focused mainly on the Git-related parts of GitLab, but it's a f These include project wikis, discussion ``walls'', and system maintenance tools. One benefit to GitLab is that, once the server is set up and running, you'll rarely need to tweak a configuration file or access the server via SSH; most administration and general usage can be accomplished through the in-browser interface. -=== Gerrit - -TODO: Gerrit - === Third Party Hosted Options If you don’t want to go through all of the work involved in setting up your own Git server, you have several options for hosting your Git projects on an external dedicated hosting site.