Wednesday, November 12, 2014

Install/setup and configure git server with gitolite and gitweb on centos/rhel 6.4

This article will guide you through the installation and configuration steps of Git/Gitolite/GitWeb server on CentOS/RHEL 6.4.
The procedure mentioned in this tutorial is tested on:

OSCentOS 6.4
Apache2.2.15
Git1.7.1
Gitoliteg3 (v3)
GitWeb1.7.1
About 
Git: It is a very popular and efficient open source Version Control System. It tracks content such as files and directories. It stores the file content in BLOBs (binary large objects). The folders are represented as trees. Each tree contains other trees (subfolders) and BLOBs along with a simple text file which consists of the mode, type, name and SHA (Secure Hash Algorithm) of each blob and subtree entry. During repository transfers, even if there are several files with the same content and different names, the GIT software will transfer the BLOB once and then expand it to the different files.
Git Web: It is used for viewing git repositories detail via Web Browser.
Gitolite: It is an access control layer on top of git.
Summary: In this tutorial we will be creating a private git server that is accessible through ssh and http both. Here Gitweb will be used for viewing git repositories detail and User/Group management is done by Gitolite.
I) Prerequisite 
1) Login to Client machine from where we will remotely manage Git repository.
Create “Git Admin” user RSA key and don’t give passphrase password (just press “Enter”),
It will create two files namely “id_rsa” and id_rsa.pub under *$HOME/.ssh* directory.
   $ ssh-keygen -t rsa -C "Git-Admin"
2) Copy the pub key (id_rsa.pub) to the */tmp* directory on our Git Server.
   $ scp ~/.ssh/id_rsa.pub root@ip-address-of-git-server:/tmp/
3) On the Git Server machine, Install the following dependency packages:
   # yum -y install git httpd perl-Time-HiRes
4) Create the “git” user/group.
   # useradd git
   # usermod -u 600 git
   # groupmod -g 600 git
5) Move the pub key of “Git-Admin” user that we have created above from */tmp* and set the appropriate permission.
   # mv /tmp/id_rsa.pub /home/git/Git-Admin.pub
   # chown git:git /home/git/Git-Admin.pub
Note: In gitolite configuration, the name to user “.pub” key (in gitolite.conf) is same as the name of user himself.
II) Gitolite Installation 
1) Login as “git” user and verify it using *whoami* and *$HOME* env. variable.
   # su -l git
   $ whoami
      git
   $ echo $HOME
      /home/git

2) Now clone the gitolite repository from github.
   $ git clone git://github.com/sitaramc/gitolite
   OR
   $ git clone https://github.com/sitaramc/gitolite
3) Create *bin* directory in “/home/git”.
   $ mkdir -p /home/git/bin
4) Installing and Setting up of Gitolite environment.
   $ gitolite/install -ln
   $ gitolite setup -pk Git-Admin.pub
5) Logout from user “git”.
   $ exit
6) Now from the “root” user check the default values for *suexec*.
   # suexec -V
7) Create a directory “bin” under “/var/www” (Web Server Root) as per *suexec* output and set the appropriate permission.
   # install -d -m 0755 -o git -g git /var/www/bin
8) Now create gitolite-suexec-wrapper.sh (bash script) with following content under “/var/www/bin”.
   # vi /var/www/bin/gitolite-suexec-wrapper.sh
 
 #!/bin/bash
 #
 # Suexec wrapper for gitolite-shell
 #
 
 export GIT_PROJECT_ROOT="/home/git/repositories"
 export GITOLITE_HTTP_HOME="/home/git"
 
 exec ${GITOLITE_HTTP_HOME}/gitolite/src/gitolite-shell
9) Set the appropriate permission.
   # chown -R git:git /var/www/bin
   # chmod 750 /var/www/bin/gitolite-suexec-wrapper.sh
   # chmod 755 /var/www/bin
9) Now modify the UMASK value in “/home/git/.gitolite.rc.
   # vi /home/git/.gitolite.rc

     From:
     UMASK => 0077
     To:
     UMASK => 0027
III) Installing GitWeb.
1) Install gitweb package using yum.
   # yum install gitweb -y
Note: By default gitweb is installed at “/var/www/git”.
2) Rename the “git” directory (under /var/www/git) to *gitweb* and change the ownership to “git”.
   # mv /var/www/git /var/www/html/gitweb
   # chown -R git:git /var/www/html/gitweb
3) Modify the value of $projectroot and $projects_list in gitweb conf file (/etc/gitweb.conf) and set the same value in“/var/www/html/gitweb/gitweb.cgifile.
   # vi /etc/gitweb.conf

     our $projectroot = "/home/git/repositories/";
     our $projects_list = "/home/git/projects.list";

   # vi /var/www/html/gitweb/gitweb.cgi
 
    our $projectroot = "/home/git/repositories";
    our $projects_list = "/home/git/projects.list";
4) Now create a dummy folder git and set the appropriate permission.
   # install -d -m 0755 -o apache -g apache /var/www/git
5) Apache Setup.
Add the following parameters at the end of apache configuration file.
   # vi /etc/httpd/conf/httpd.conf

    

        # You can comment out the below 3 lines and put correct value as per your server information
        #  ServerName        gitserver.example.com
        #  ServerAlias       gitserver
        ServerAdmin       youremailid@example.com
        DocumentRoot /var/www/git
    
        Options       None
        AllowOverride none
        Order         allow,deny
        Allow         from all

    

    SuexecUserGroup git git
    ScriptAlias /git/ /var/www/bin/gitolite-suexec-wrapper.sh
    ScriptAlias /gitmob/ /var/www/bin/gitolite-suexec-wrapper.sh

    
        AuthType Basic
        AuthName "Git Access"
        Require valid-user
        AuthUserFile /etc/httpd/conf/git.passwd
    

    
Note: If you have setup DNS and hostname (FQDN) then uncomment the ServerName and ServerAlias directive.
6) Now update the gitweb apache conf file “/etc/httpd/conf.d/git.conf.
   # vi /etc/httpd/conf.d/git.conf 
 
 Alias /gitweb /var/www/html/gitweb

        
   Options +ExecCGI
   AddHandler cgi-script .cgi
   DirectoryIndex gitweb.cgi
 
        
   AuthType Basic
   AuthName "Git Access"
   Require valid-user
   AuthUserFile /etc/httpd/conf/git.passwd
        
7) We will create Apache Basic auth username and password using *htpasswd*.
   # htpasswd -c /etc/httpd/conf/git.passwd admin
   # htpasswd /etc/httpd/conf/git.passwd userxyz1
   # htpasswd /etc/httpd/conf/git.passwd userxyz2
Note: We used first time “-c flag” to create new password file (/etc/httpd/conf/git.passwd).
8) Restart the Apache Web service and enable it to autostart in runlevel (3 & 5) during system startup.
   # service httpd restart
   # chkconfig httpd on
9) Verify the GitWeb is running fine using your favorite browser.
   http://(ip-address OR FQDN) of git-server/gitweb/
10) If you are unable to view this page or testing.git git repo is not showing up, then either IPTables or SELinux is blocking it.
a) So try to disable iptables temporary and check.
   # service iptables stop
b) See my docs to disable SELinux temporary.
11) Verify that you are able to clone the git using http from Client Machine.
   $ mkdir ~/git-repo/
   $ cd ~/git-repo
   $ git clone git@GitServerIP-or-FQDN:testing.git
IV) Manage user and group of Git Server (from remote client Machine).
1) To manage Git user and groups on Git-Server, we need to clone the gitolite-admin repo.
   $ cd ~/git-repo
   $ git config --global user.name "Git-Admin"
   $ git config --global user.email "youremailid@example.com"
   $ git clone git@GitServerIP-or-FQDN:gitolite-admin.git
2) Adding new users and repos (Client Machine).
First, obtain pubkeys for your users. We will start with the example users “sanjay” and “shyam”.
Ask both of them to generate a keypair just as we did in upper most section of this doc., and send you their keys somehow. Save them with their respective names (sanjay.pub and shyam.pub) in /tmp of your workstation.
Now you have your two users, let us assume that your two new repos are “dev” and “prod”. The “dev” repo must be writeable by sanjay, but read-only to shyam. The “prod” repo is the other way around — writeable by shyam, read-only to sanjay.
Now, on your client machine under “gitolite-admin/keydir” copy the pub keys of sanjay and shyam:
   $ cd ~/git-repo/gitolite-admin
   $ cp /tmp/sanjay.pub /tmp/shyam.pub keydir
3) Now we need to update the gitolite conf file (gitolite.conf).
   $ vim conf/gitolite.conf

 repo    gitolite-admin
        RW+     =   sena

 repo    testing
        RW+     =   @all

 repo    dev
        RW      =   sanjay
        R       =   shyam

 repo    prod
        RW      =   shyam
        R       =   sanjay
Note: R is for Read and W is for Write.
4) Now we need to push the changes of “gitolite.conf” to Git Server.
   $ git add keydir conf
   $ git commit -m 'added users sanjay and shyam, repos dev and prod'
       [master 4932ca2] added users sanjay and shyam, repos dev and prod
       3 files changed, 10 insertions(+), 0 deletions(-)
       create mode 100644 keydir/sanjay.pub
       create mode 100644 keydir/shyam.pub

   $ git push origin master
       Counting objects: 11, done.
       Delta compression using up to 2 threads.
       Compressing objects: 100% (6/6), done.
       Writing objects: 100% (7/7), 1.21 KiB, done.
       Total 7 (delta 0), reused 0 (delta 0)
       remote: Initialized empty Git repository in /home/git/repositories/dev.git/
       remote: Initialized empty Git repository in /home/git/repositories/prod.git/
       To git@10.42.80.70:gitolite-admin.git
          7dd3afe..4932ca2  master -> master

V) Creating repository on Git Server
Login in Git Server as root.And then change to git user.
   # su -l git
   $ cd repositories
   $ mkdir test-repo.git
   $ cd test-repo.git
   $ git --bare init
   $ git update-server-info
VI) Usefull Git Command
1) Setting up of Git Environment variable.
   $ git config --global user.email "you@example.com"
   $ git config --global user.name "Your Name"
   $ git config --global core.editor "vim"
   $ git clone gitolite@GitServerIP-or-FQDN:dev.git

2) Adding file1 in Git.
   $ git add file1
   $ git commit -m "Adding file1"
   $ git push origin master

3) Deleting file in Git.
   $ rm file1
   $ git commit -m "Removing file file1"
   $ git push origin master

4) Sync the file to local File System from Git Server if someone deleted file locally.
   $ git reset --hard
   $ git checkout filename

5) Pull the already created git repo from Git Server.

   $ git clone gitolite@GitServerIP-or-FQDN:ops.git
   $ cd ops
   $ git pull