James Moger
2012-10-23 2d48e28bf1068b20129b2e3d5b96ecaff48f9f2f
docs/01_setup.mkd
@@ -8,7 +8,11 @@
Open `web.xml` in your favorite text editor and make sure to review and set:
    - <context-parameter> *git.repositoryFolder* (set the full path to your repositories folder)
    - <context-parameter> *groovy.scriptsFolder* (set the full path to your Groovy hook scripts folder)
    - <context-parameter> *groovy.grapeFolder* (set the full path to your Groovy Grape artifact cache)
    - <context-parameter> *web.projectsFile* (set the full path to your projects metadata file)
    - <context-parameter> *realm.userService* (set the full path to `users.conf`)
    - <context-parameter> *git.packedGitLimit* (set larger than the size of your largest repository)
    - <context-parameter> *git.streamFileThreshold* (set larger than the size of your largest committed file)
5. You may have to restart your servlet container. 
6. Open your browser to <http://localhost/gitblit> or whatever the url should be.
7. Enter the default administrator credentials: **admin / admin** and click the *Login* button  
@@ -22,10 +26,13 @@
Open `gitblit.properties` in your favorite text editor and make sure to review and set:
    - *git.repositoryFolder* (path may be relative or absolute)
    - *groovy.scriptsFolder* (path may be relative or absolute)
    - *groovy.grapeFolder* (path may be relative or absolute)
    - *server.tempFolder* (path may be relative or absolute)
    - *server.httpPort* and *server.httpsPort*
    - *server.httpBindInterface* and *server.httpsBindInterface*  
    **https** is strongly recommended because passwords are insecurely transmitted form your browser/git client using Basic authentication!
    - *git.packedGitLimit* (set larger than the size of your largest repository)
    - *git.streamFileThreshold* (set larger than the size of your largest committed file)
3. Execute `gitblit.cmd` or `java -jar gitblit.jar` from a command-line
4. Wait a minute or two while all dependencies are downloaded and your self-signed *localhost* certificate is generated.  
    Please see the section titled **Creating your own Self-Signed Certificate** to generate a certificate for *your hostname*.
@@ -86,6 +93,7 @@
    --useNio               Use NIO Connector else use Socket Connector.
    --httpPort             HTTP port for to serve. (port <= 0 will disable this connector)
    --httpsPort            HTTPS port to serve.  (port <= 0 will disable this connector)
    --ajpPort              AJP port to serve.  (port <= 0 will disable this connector)
    --storePassword        Password for SSL (https) keystore.
    --shutdownPort         Port for Shutdown Monitor to listen on. (port <= 0 will disable this monitor)
    --tempFolder           Folder for server to extract built-in webapp
@@ -140,19 +148,24 @@
   Allow from all
&lt;/Proxy&gt;
 
# Turn on Proxy status reporting at /status
# This should be better protected than: Allow from all
ProxyStatus On
&lt;Location /status&gt;
   SetHandler server-status
   Order Deny,Allow
   Allow from all
&lt;/Location&gt;
# The proxy context path must match the Gitblit context path.
# For Gitblit GO, see server.contextPath in gitblit.properties.
#ProxyPass /gitblit http://localhost:8080/gitblit
#ProxyPassreverse /gitblit http://localhost:8080/gitblit
# If your httpd frontend is https but you are proxying http Gitblit WAR or GO
#Header edit Location &#94;http://([&#94;&#8260;]+)/gitblit/ https://&#36;1/gitblit/
# Additionally you will want to tell Gitblit the original scheme and port
#RequestHeader set X-Forwarded-Proto https
#RequestHeader set X-Forwarded-Port 443
# If you are using subdomain proxying then you will want to tell Gitblit the appropriate
# context path for your repository url.
# If you are not using subdomain proxying, then ignore this setting.
#RequestHeader set X-Forwarded-Context /
#ProxyPass /gitblit ajp://localhost:8009/gitblit
%ENDCODE%  
**Please** make sure to:  
@@ -221,7 +234,7 @@
       federationSets = 
#### Repository Names
Repository names must be unique and are CASE-SENSITIVE ON CASE-SENSITIVE FILESYSTEMS.  The name must be composed of letters, digits, or `/ _ - .`<br/>
Repository names must be unique and are CASE-SENSITIVE ON CASE-SENSITIVE FILESYSTEMS.  The name must be composed of letters, digits, or `/ _ - . ~`<br/>
Whitespace is illegal.
Repositories can be grouped within subfolders.  e.g. *libraries/mycoollib.git* and *libraries/myotherlib.git*
@@ -230,6 +243,85 @@
#### Repository Owner
The *Repository Owner* has the special permission of being able to edit a repository through the web UI.  The Repository Owner is not permitted to rename the repository, delete the repository, or reassign ownership to another user.
### Access Restrictions and Access Permissions
![permissions matrix](permissions_matrix.png "Permissions and Restrictions")
#### Discrete Permissions (Gitblit v1.2.0+)
Since v1.2.0, Gitblit supports more discrete permissions.  While Gitblit does not offer a built-in solution for branch-based permissions like Gitolite, it does allow for the following repository access permissions:
- **V** (view in web ui, RSS feeds, download zip)
- **R** (clone)
- **RW** (clone and push)
- **RWC** (clone and push with ref creation)
- **RWD** (clone and push with ref creation, deletion)
- **RW+** (clone and push with ref creation, deletion, rewind)
These permission codes are combined with the repository path to create a user permission:
    RW:mygroup/myrepo.git
#### Discrete Permissions with Regex Matching (Gitblit v1.2.0+)
Gitblit also supports *case-insensitive* regex matching for repository permissions.  The following permission grants push privileges to all repositories in the *mygroup* folder.
    RW:mygroup/.*
##### Exclusions
When using regex matching it may also be useful to exclude specific repositories or to exclude regex repository matches.  You may specify the **X** permission for exclusion.  The following example grants clone permission to all repositories except the repositories in mygroup.  The user/team will have no access whatsoever to these repositories.
    X:mygroup/.*
    R:.*
##### Order is Important
The preceding example should suggest that order of permissions is important with regex matching.  Here are the rules for determining the permission that is applied to a repository request:
1. If the user is an admin or repository owner, then RW+
2. Else if user has an explicit permission, use that
3. Else check for the first regex match in user permissions
4. Else check for the HIGHEST permission from team memberships
    1. If the team is an admin team, then RW+
    2. Else if a team has an explicit permission, use that
    3. Else check for the first regex match in team permissions
#### No-So-Discrete Permissions (Gitblit <= v1.1.0)
Prior to v1.2.0, Gitblit has two main access permission groupings:
1. what you are permitted to do as an anonymous user
2. **RW+** for any permitted user
#### Committer Verification
You may optionally enable committer verification which requires that each commit be committed by the authenticated user pushing the commits.  i.e. If Bob is pushing the commits, Bob **must** be the committer of those commits.
**How is this enforced?**
Bob must set his *user.name* and *user.email* values for the repository to match his Gitblit user account **BEFORE** committing to his repository.
<pre>
[user "bob"]
    displayName = Bob Jones
    emailAddress = bob@somewhere.com
</pre>
<pre>
    git config user.name "Bob Jones"
    git config user.email bob@somewhere.com
</pre>
or
    git config user.name bob
    git config user.email bob@somewhere.com
If the Gitblit account does not specify an email address, then the committer email address is ignored.  However, if the account does specify an address it must match the committer's email address.  Display name or username can be used as the committer name.
All checks are case-insensitive.
**What about merges?**
You can not use fast-forward merges on your client when using committer verification.  You must specify *--no-ff* to ensure that a merge commit is created with your identity as the committer.  Only the first parent chain is traversed when verifying commits.
### Teams
@@ -244,11 +336,13 @@
       password = admin
       role = "#admin"
       role = "#notfederated"
       repository = repo1.git
       repository = repo2.git
       repository = RW+:repo1.git
       repository = RW+:repo2.git
       
   [user "hannibal"]
      password = bossman
      repository = RWD:topsecret.git
      repository = RW+:ateam/[A-Za-z0-9-~_\\./]+
   [user "faceman"]
      password = vanity
@@ -264,7 +358,7 @@
      user = faceman
      user = murdock
      user = babaracus
      repository = topsecret.git
      repository = RW:topsecret.git
      mailingList = list@ateam.org
      postReceiveScript = sendmail
@@ -278,19 +372,119 @@
    username=password,role1,role2,role3...
    @teamname=&mailinglist,!username1,!username2,!username3,repository1,repository2,repository3...
#### Usernames
### Usernames
Usernames must be unique and are case-insensitive.  
Whitespace is illegal.
#### Passwords
### Passwords
User passwords are CASE-SENSITIVE and may be *plain*, *md5*, or *combined-md5* formatted (see `gitblit.properties` -> *realm.passwordStorage*).
#### User Roles
There are two actual *roles* in Gitblit: *#admin*, which grants administrative powers to that user, and *#notfederated*, which prevents an account from being pulled by another Gitblit instance.  Administrators automatically have access to all repositories.  All other *roles* are repository names.  If a repository is access-restricted, the user must have the repository's name within his/her roles to bypass the access restriction.  This is how users are granted access to a restricted repository.
### User Roles
There are four actual *roles* in Gitblit:
## Authentication and Authorization Customization
- *#admin*, which grants administrative powers to that user
- *#notfederated*, which prevents an account from being pulled by another Gitblit instance
- *#create*, which allows the user the power to create personal repositories
- *#fork*, which allows the user to create a personal fork of an existing Gitblit-hosted repository
### Customize Authentication Only
Administrators automatically have access to all repositories.  All other *roles* are repository permissions.  If a repository is access-restricted, the user must have the repository's name within his/her roles to bypass the access restriction.  This is how users are granted access to a restricted repository.
**NOTE:**
The following roles are equivalent:
- myrepo.git
- RW+:myrepo.git
This is to preserve backwards-compatibility with Gitblit <= 1.1.0 which granted rewind power to all access-permitted users.
### Personal Repositories & Forks
Personal Repositories and Forks are related but are controlled individually.
#### Creating a Personal Repository
A user may be granted the power to create personal repositories by specifying the *#create* role through the web ui or through the RPC mechanism via the Gitblit Manager.  Personal repositories are exactly like common/shared repositories except that the owner has a few additional administrative powers for that repository, like rename and delete.
#### Creating a Fork
A user may also be granted the power to fork an existing repository hosted on your Gitblit server to their own personal clone by specifying the *#fork* role through the web ui or via the Gitblit Manager.
Forks are mostly likely personal repositories or common/shared repositories except for two important differences:
1. Forks inherit a view/clone access list from the origin repository.
i.e. if Team A has clone access to the origin repository, then by default Team A also has clone access to the fork.  This is to facilitate collaboration.
2. Forks are always listed in the fork network, regardless of any access restriction set on the fork.
In other words, if you fork *RepoA.git* to *~me/RepoA.git* and then set the access restriction of *~me/RepoA.git* to *Authenticated View, Clone, & Push* your fork will still be listed in the fork network for *RepoA.git*.
If you really must have an invisible fork, the clone it locally, create a new personal repository for your invisible fork, and push it back to that personal repository.
## Alternative Authentication and Authorization
### LDAP Authentication
*SINCE 1.0.0*
LDAP can be used to authenticate Users and optionally control Team memberships.  When properly configured, Gitblit will delegate authentication to your LDAP server and will cache some user information in the usual users file (.conf or .properties).
When using the LDAP User Service, new user accounts can not be manually created from Gitblit.  Gitblit user accounts are automatically created for new users on their first succesful authentication through Gitblit against the LDAP server.  It is also important to note that the LDAP User Service does not retrieve or store user passwords nor does it implement any LDAP-write functionality.
To use the *LdapUserService* set *realm.userService=com.gitblit.LdapUserService* in your `gitblit.properties` file or your `web.xml` file and then configure the *realm.ldap* settings appropriately for your LDAP environment.
#### Example LDAP Layout
![block diagram](ldapSample.png "LDAP Sample")
Please see [ldapUserServiceSampleData.ldif](https://github.com/gitblit/gitblit/blob/master/tests/com/gitblit/tests/resources/ldapUserServiceSampleData.ldif) to see the data in LDAP that reflects the above picture.
#### Gitblit Settings for Example LDAP Layout
The following are the settings required to configure Gitblit to authenticate against the example LDAP server with LDAP-controlled team memberships.
<table class="table">
<thead>
<tr><th>parameter</th><th>value</th><th>description</th></tr>
</thead>
<tbody>
<tr>
  <th>realm.ldap.server</th><td>ldap://localhost:389</td>
  <td>Tells Gitblit to connect to the LDAP server on localhost port 389.  The URL Must be of form ldap(s)://&lt;server&gt;:&lt;port&gt; with port being optional (389 for ldap, 636 for ldaps).</td>
</tr>
<tr>
  <th>realm.ldap.username</th><td>cn=Directory Manager</td>
  <td>The credentials that will log into the LDAP server</td>
</tr>
<tr>
  <th>realm.ldap.password</th><td>password</td>
  <td>The credentials that will log into the LDAP server</td>
</tr>
<tr>
  <th>realm.ldap.backingUserService</th><td>users.conf</td>
  <td>Where to store all information that is used by Gitblit.  All information will be synced here upon user login.</td>
</tr>
<tr>
  <th>realm.ldap.maintainTeams</th><td>true</td>
  <td>Are team memberships maintained in LDAP (<em>true</em>) or manually in Gitblit (<em>false</em>).</td>
</tr>
<tr>
  <th>realm.ldap.accountBase</th><td>OU=Users,OU=UserControl,OU=MyOrganization,DC=MyDomain</td>
  <td>What is the root node for all users in this LDAP system.  Subtree searches will start from this node.</td>
</tr>
<tr>
  <th>realm.ldap.accountPattern</th><td>(&(objectClass=person)(sAMAccountName=${username}))</td><td>The LDAP search filter that will match a particular user in LDAP.  ${username} will be replaced with whatever the user enters as their username in the Gitblit login panel.</td>
</tr>
<tr>
  <th>realm.ldap.groupBase</th><td>OU=Groups,OU=UserControl,OU=MyOrganization,DC=MyDomain</td>
  <td>What is the root node for all teams in this LDAP system.  Subtree searches will start from this node.</td>
</tr>
<tr>
  <th>realm.ldap.groupMemberPattern</th><td>(&(objectClass=group)(member=${dn}))</td><td>The LDAP search filter that will match all teams for the authenticating user.  ${username} will be replaced with whatever the user enters as their username in the Gitblit login panel.  Anything else in ${} will be replaced by Attributes from the User node.</td>
</tr>
<tr>
  <th>realm.ldap.admins</th><td>@Git_Admins</td><td>A space-delimited list of usernames and/or teams that indicate admin status in Gitblit.  Teams are referenced with a leading <em>@</em> character.</td>
</tr>
</tbody>
</table>
#### LDAP In-Memory Server
You can start Gitblit GO with an in-memory LDAP server by specifying the *--ldapLdifFile* command-line argument.  The LDAP server will listen on localhost of the port specified in *realm.ldap.url* of `gitblit.properties`.  Additionally, a root user record is automatically created for *realm.ldap.username* and *realm.ldap.password*.  Please note that the ldaps:// protocol is not supported for the in-memory server.
### Custom Authentication
This is the simplest choice where you implement custom authentication and delegate all other standard user and team operations to one of Gitblit's user service implementations.  This choice insulates your customization from changes in User and Team model classes and additional API that may be added to IUserService.
Please subclass [com.gitblit.GitblitUserService](https://github.com/gitblit/gitblit/blob/master/src/com/gitblit/GitblitUserService.java) and override the *setup()* and *authenticate()* methods.  
@@ -300,7 +494,7 @@
Your subclass must be on Gitblit's classpath and must have a public default constructor.  
### Customize Everything
### Custom Everything
Instead of maintaining a `users.conf` or `users.properties` file, you may want to integrate Gitblit into an existing environment.
You may use your own custom *com.gitblit.IUserService* implementation by specifying its fully qualified classname in the *realm.userService* setting.
@@ -334,6 +528,37 @@
Some sample scripts are included in the GO and WAR distributions to show you how you can tap into Gitblit with the provided bound variables.  Additional implementation details may be specified in the header comment of these examples.
Hook contributions and improvements are welcome.
### Grapes
*SINCE 1.0.0*
[Grape](http://groovy.codehaus.org/Grape) lets you quickly add maven repository dependencies to your Groovy hook script.
<blockquote>Grape (The Groovy Adaptable Packaging Engine or Groovy Advanced Packaging Engine) is the infrastructure enabling the grab() calls in Groovy, a set of classes leveraging <a href="http://ant.apache.org/ivy">Ivy</a> to allow for a repository driven module system for Groovy. This allows a developer to write a script with an essentially arbitrary library requirement, and ship just the script. Grape will, at runtime, download as needed and link the named libraries and all dependencies forming a transitive closure when the script is run from existing repositories such as Ibiblio, Codehaus, and java.net.</blockquote>
%BEGINCODE%
// create and use a primitive array
import org.apache.commons.collections.primitives.ArrayIntList
@Grab(group='commons-primitives', module='commons-primitives', version='1.0')
def createEmptyInts() { new ArrayIntList() }
def ints = createEmptyInts()
ints.add(0, 42)
assert ints.size() == 1
assert ints.get(0) == 42
%ENDCODE%
### Custom Fields
*SINCE 1.0.0*
Gitblit allows custom repository string fields to be defined in `gitblit.properties` or `web.xml`.  Entry textfields are automatically created for these fields in the Edit Repository page of Gitblit and the Edit Repository dialog of the Gitblit Manager.  These fields are accessible from your Groovy hook scripts as
    repository.customFields.myField
This feature allows you to customize the behavior of your hook scripts without hard-coding values in the hook scripts themselves.
### Pre-Receive
@@ -375,6 +600,58 @@
**NOTE:**  
Care should be taken when devising your notification scheme as it relates to any VIEW restricted repositories you might have.  Setting a global mailing list and activating push notifications for a VIEW restricted repository may send unwanted emails.
## Lucene Search Integration
*SINCE 0.9.0*
Repositories may optionally be indexed using the Lucene search engine.  The Lucene search offers several advantages over commit-traversal search:
1. very fast commit and blob searches
2. multi-term searches
3. term-highlighted and syntax-highlighted fragment matches
4. multi-repository searches
### How do I use it?
First you must ensure that *web.allowLuceneIndexing* is set *true* in `gitblit.properties` or `web.xml`.  Then you must understand that Lucene indexing is an opt-in feature which means that no repositories are automatically indexed.
Like anything else, this design has pros and cons.
#### Pros
1. no wasted cycles indexing repositories you will never search
2. you specify exactly what branches are indexed; experimental/dead/personal branches can be ignored
#### Cons
1. you specify exactly what branches are indexed
#### I have 300 repositories and you want me to specify indexed branches on each one??
Yeah, I agree that is inconvenient.
If you are using Gitblit GO there is a utility script `add-indexed-branch.cmd` which allows you to specify an indexed branch for many repositories in one step.
If you are using Gitblit WAR then, at present, you are out of luck unless you write your own script to traverse your repositories and use native Git to manipulate each repository config.
    git config --add gitblit.indexBranch "default"
    git config --add gitblit.indexBranch "refs/heads/master"
#### Indexing Branches
You may specify which branches should be indexed per-repository in the *Edit Repository* page.  New/empty repositories may only specify the *default* branch which will resolve to whatever commit HEAD points to or the most recently updated branch if HEAD is unresolvable.
Indexes are built and incrementally updated on a 2 minute cycle so you may have to wait a few minutes before your index is built or before your latest pushes get indexed.
**NOTE:**
After specifying branches, only the content from those branches can be searched via Gitblit.  Gitblit will automatically redirect any queries entered on a repository's search box to the Lucene search page. Repositories that do not specify any indexed branches will use the traditional commit-traversal search.
#### Adequate Heap
The initial indexing of an existing repository can potentially exhaust the memory allocated to your Java instance and may throw OutOfMemory exceptions.  Be sure to provide your Gitblit server adequate heap space to index your repositories.  The heap is set using the *-Xmx* JVM parameter in your Gitblit launch command (e.g. -Xmx1024M).
#### Why does Gitblit check every 2 mins for repository/branch changes?
Gitblit has to balance its design as a complete, integrated Git server and its utility as a repository viewer in an existing Git setup.
Gitblit could build indexes immediately on *edit repository* or on *receiving pushes*, but that design would not work if someone is pushing via ssh://, git://, or file:// (i.e. not pushing to Gitblit http(s)://).  For this reason Gitblit has a polling mechanism to check for ref changes every 2 mins.  This design works well for all use cases, aside from adding a little lag in updating the index.
## Client Setup and Configuration
### Https with Self-Signed Certificates
You must tell Git/JGit not to verify the self-signed certificate in order to perform any remote Git operations.
@@ -398,4 +675,5 @@
<pre>https://yourserver/git/your/repository</pre>
- **Command-line Git**  
My testing indicates that your username must be embedded in the url.  YMMV.  
<pre>https://username@yourserver/git/your/repository</pre>
<pre>https://username@yourserver/git/your/repository</pre>