1. Home
  2. Tutorials
  3. GIT Server Configuration
Yolinux.com Tutorial

GIT Server Configuration:

Configuration of a GIT server "bare" repository using SSH or "Smart HTTP" for remote access.

Description:

GIT can be configured for use as a local user change management (CM) or system CM repository or for multiple users using a server configuration with SSH or "Smart HTTP" remote access. This tutorial will cover SSH and HTTP GIT server configurations.

A "bare" repository will be generated for remote access. A "bare" repository implies that there is only a GIT repository with no user working files as this is not to be used for code development and only as a repository.

SSH vs HTTP: Accessing a Git repository by ssh requires that all users have a shell account on the server and have read and write privileges over the repository. Http/https access can allow read only access as well as read/write to a more privileged group of users using Apache httpd authentication and authorization rules. This flexibility makes a "smart http" the preferred choice for internet based Git server installations.

GIT Installation:

SSH Prerequisites:

  • Red Hat/CentOS/AWS: openssh, openssh-clients, openssh-askpass, openssh-server
  • Ubuntu/Debian: ssh, openssh-client, openssh-server

HTTP Prerequisites:

  • Apache httpd web server:
    • Red Hat/CentOS/AWS: httpd
    • Ubuntu/Debian: apache2
  • Apache modules: mod_cgi, mod_alias, mod_env, mod_rewrite, mod_dav
    Verify with the command httpd -M or
    CentOS/Red Hat: verify the configuration in /etc/httpd/conf/httpd.conf
    Ubuntu: enable the modules with the command: a2enmod cgi alias env
  • Perl module: Authen::SASL
  • Perl module: GSSAPI
  • Perl module: Net::SMTP
  • Perl module: Term::ReadKey

GIT (Red Hat 6.x RPM Installation:

Install from RPM RHEL6 x86_64 RPM Download GIT 2.12.0
RPMs available:
  • git2u-core - Core package of git with minimal functionality
    commands: /usr/bin/git, git-receive-pack, git-shell, git-upload-archive, git-upload-pack
  • git2u-core-doc - Documentation files for git-core
    Man pages (1,5,7)
  • git2u - Fast Version Control System
    man pages for: gitweb, gitweb.conf, git-difftool, git-instaweb
  • git2u-all - Meta-package to pull in all git tools
  • git2u-daemon - Git protocol dæmon
  • git2u-email - Git tools for sending email
    git-send-email
  • git2u-gitk - Git revision tree visualizer
  • git2u-gitweb - Simple web interface to git repositories
    Web front-end: /var/www/git/gitweb.cgi, /etc/gitweb.conf, /etc/httpd/conf.d/git.conf
  • git2u-gui - Git GUI tool
    GUI tools: "git gui", git citool (alternative to commit) and man pages
See the EPEL or PBone RPM repositories for dependencies (eg perl-Authen-SASL.noarch, perl-GSSAPI.x86_64, perl-Net-SMTP-SSL.noarch or perl-TermReadKey.x86_64).

SSH Git Server Configuration:

Bare Repository Creation:

Generate the repository and allow the the user remote shell access to the git repository:
  • mkdir /srv/git/
  • git init --bare --shared=group /srv/git/projectx.git/
  • cd /srv/git/projectx.git/
  • cp hooks/post-update.sample hooks/post-update
  • chgrp -R dev /srv/git/projectx.git/
    chmod ug+rw -R /srv/git/projectx.git/
    Change ownership of all files to the software developers group. All programmers must be part of this group "dev" in order to have access to the repository. Note that this requires all developers to have a login shell account on the system. For more on group access see managing Linux groups
  • Set the repository "description": edit file /srv/git/projectx.git/description

Note:
  • git init:
    • --bare: Create a bare repository. A bare repository has no working files and is a repository only. Developers do not work and edit files in this repository as it has no working area. If GIT_DIR environment is not set or a directory is not specified, it is set to the current working directory.
    • --shared: =(false|true|umask|group|all|world|everybody|0xxx)
      Specify that the Git repository is to be shared among several users. This allows users belonging to the same group to push into that repository. When not specified, Git will use permissions reported by umask

See our sshd server configuration tutorial

Smart HTTP Git Server Configuration:

Bare Repository Creation:

Generate the repository and allow the Apache httpd web server process to access the repository:
  • mkdir /srv/git/projectx.git
  • git init --bare --shared /srv/git/projectx.git/
  • cd /srv/git/projectx.git/
  • cp hooks/post-update.sample hooks/post-update
  • git config http.receivepack true
  • git config http.uploadpack true
  • git update-server-info
  • chown -R apache.apache /srv/git/projectx.git/
  • Set the repository "description": edit file /srv/git/projectx.git/description

Configure the Apache httpd server:

File: /etc/httpd/conf.d/GIT.conf
SetEnv GIT_PROJECT_ROOT /srv/git

# 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.
SetEnv GIT_HTTP_EXPORT_ALL

# Required for git clone
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/

# Allow execution of CGI
<Directory /usr/libexec/git-core/>
  AllowOverride None
  Options None
  Order allow,deny
  Allow from all
# Apache 2.4: Require all granted
#  DirectoryIndex git-web--browse
</Directory>

#RewriteCond %{QUERY_STRING} service=git-receive-pack [OR] 
RewriteCond %{REQUEST_URI} /git-receive-pack$
RewriteRule ^/git/ - [E=AUTHREQUIRED:yes]

# Repository URL access configuration
<LocationMatch "^/git/.*$">
  Order deny,allow
  Deny from env=AUTHREQUIRED
  AuthType Basic
  AuthName "Megacorp directory services login"
  AuthBasicProvider ldap
  AuthzLDAPAuthoritative on
  AuthLDAPURL "ldap://ldap.megacorp.com:389/ou=person,o=megacorp.com,c=us?uid?sub"
  Include authorized-users.txt
</LocationMatch>

# required even if mod rewrite is active!!!
<LocationMatch "^/git/.*/git-receive-pack$">
  Order deny,allow
  AuthType Basic
  AuthName "Megacorp directory services login"
  AuthBasicProvider ldap
  AuthzLDAPAuthoritative on
  AuthLDAPURL "ldap://ldap.megacorp.com:389/ou=person,o=megacorp.com,c=us?uid?sub"
  Include authorized-users.txt
</LocationMatch>

# Allow authenticated access to the GIT repository on disk
<Location "/srv/git">
# Use authentication for both read/write
  Order deny,allow
  AuthType Basic
  AuthName "Megacorp directory services login"
  AuthBasicProvider ldap
  AuthzLDAPAuthoritative on
  AuthLDAPURL "ldap://ldap.megacorp.com:389/ou=person,o=megacorp.com,c=us?uid?sub"
  Include authorized-users.txt
</Location>
Where /etc/httpd/authorized-users.txt is a shared include file of authorized users shared among various web-apps:
# List of authorized LDAP users
Require ldap-user user1 user2 user3
This example shows LDAP authentication. For other Apache httpd authentication methods see: Apache Web Login Authentication

Note that many of the configuration options detailed on the GIT manual pages do NOT work:
  • The following line causes a "git push" to fail:
    RewriteCond %{QUERY_STRING} service=git-receive-pack [OR]
    Also note that the syntax "[OR]" is valid Apache httpd configuration syntax and does not imply choosing one or the other.

  • The following environment variable statement breaks the configuration:
    SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER

  • The following ScriptAliasMatch will also break the configuration:
    ScriptAliasMatch \
      "(?x)^/(.*/(HEAD | \
      info/refs | \
      objects/(info/[^/]+ | \
      [0-9a-f]{2}/[0-9a-f]{38} | \
      pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
      git-(upload|receive)-pack))$" \
      "/usr/libexec/git-core/git-http-backend/$1"
        

Restart web server to pick up the configuration changes:
  • Ubuntu: apache2ctl -k graceful
  • RedHat: service httpd restart

Using the GIT Server:

Now that the git server repository has been created, it is time to add files. Git stores files and will not store empty directories.

  • Set user identity:
    • git config --global user.name "John Doe"
    • git config --global user.email john.doe@megacorp.com
    This configures user preferences: ~/.gitconfig
    [user]
            name = John Doe
            email = john.doe@megacorp.com
        
  • Generate a local "clone" repository. This checks out the entire repository and all of its history:
    • Smart http:
      [prompt]$ git clone http://git.megacorp.com/git/repo/projectx.git
      Cloning into 'projectx'...
      warning: You appear to have cloned an empty repository.
          
      The first time a check-out is made to a new bare repository, it will be a "clone" on an empty repository with nothing in it.
    • OR ssh:
      [prompt]$ git clone ssh://user@git.megacorp.com:/srv/git/repo/projectx.git
      Cloning into 'projectx'...
      The authenticity of host 'git.megacorp.com (192.168.1.2)' can't be established.
      ECDSA key fingerprint is ce:68:f4:3d:fa:58:b7:49:92:36:63:a7:82:c2:df:a4.
      Are you sure you want to continue connecting (yes/no)? yes
      Warning: Permanently added '192.168.1.2' (ECDSA) to the list of known hosts.
      user@192.168.1.2's password:
      warning: You appear to have cloned an empty repository.
          
  • Add files (create or copy) to the local working repository:
    [prompt]$ cd projectx
    [prompt]$ mkdir src
    [prompt]$ touch src/Readme.txt
    [prompt]$ git add --all
    [prompt]$ git commit -m "Add user files"
    [master (root-commit) 1184908] Add user files
     5 files changed, 0 insertions(+), 0 deletions(-)
     create mode 100644 src/Readme.txt
    
  • Push changes to the local repository to the Git server:
    [prompt]$ git push origin master
    user@192.168.1.2's password: 
    Counting objects: 4, done.
    Writing objects: 100% (4/4), 252 bytes | 0 bytes/s, done.
    Total 4 (delta 0), reused 0 (delta 0)
    To [protocol ssh or http]://user@192.168.1.2:/path/to/repo/projectx.git
     * [new branch]      master -> master
        
  • Query your repository:
    • Smart http:
      [prompt]$ git remote -v
      origin	http://git.megacorp.com/git/repo/projectx.git (fetch)
      origin	http://git.megacorp.com/git/repo/projectx.git (push)
          
    • OR ssh:
      [prompt]$ git remote -v
      origin	ssh://user@git.megacorp.com/git/repo/projectx.git (fetch)
      origin	ssh://user@git.megacorp.com/git/repo/projectx.git (push)
          

Pro Tip for ssh users: Generate an ssh key to automatically authenticate your connection so that you do not have to enter your password each time.
See ssh-keygen man page

[Potential Pitfall]: ssh connection error:

[prompt]$ git clone ssh://user@git.megacorp.com:/srv/git/repo/projectx.git
Cloning into 'projectx'...
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
...
    
Solution: ssh-keygen -f ~/.ssh/known_hosts -R git.megacorp.com
or clear the contents of ~/.ssh/known_hosts

[Potential Pitfall]: Vague git error about a valid git repository is actually a proxy error:

[prompt]$ git clone http://git.megacorp.com/git/repo/projectx.git
Cloning into 'projectx'...
fatal: http://git.megacorp.com/git/projectx.git/info/refs not valid: is this a git repository?
    
Proxies are configured by setting the environment variable http_proxy or in ~/.gitconfig.
[prompt]$ env | grep http_proxy
    
If blank, no proxy is set. If it is set, the proxy may be routing your traffic outside your network rather than to your locally hosted server.
Fix: unset http_proxy

[Potential Pitfall]: Http server works for clone but not a push. This is typically an Apache httpd web server configuration problem. Check the server logs /var/log/httpd/error_log

[prompt]$ git push origin master
fatal: http://git.megacorp.com/git/projectx.git/info/refs not valid: is this a git repository?
    

[Potential Pitfall]: When you "push" you may get the warning:

*** Project description file hasn't been set
    
or in gitweb, you may get the following for the description: Un-named repository; edit this file 'description' to name the repository.
Solution: on the origin server, edit the file: /srv/git/projectx.git/description and change from the above default message to something repository specific, for example: Our awesome ProjectX git repository

GITIGNORE:

There will probably be files that you have no interest storing in the CM repository such as build artifacts. Git can be configured to ignore these files by generating the file .gitignore in the top directory of your repository. eg: src/projectx.git/.gitignore

Example .gitignore for C/C++ developers:
core.*
*.o
*.a
*.so
*.dll
*.lib
a.out

Example .gitignore for Java developers:
*.jar
*.class
/**/dist/
/**/build/

Add the following for Netbeans developers:
private.*
/**/nbproject/private/

GIT Man Pages:

Git commands are separated into two categories:

  1. high level ("porcelain") commands
  2. low level ("plumbing") commands

High Level "porcelain" Commands:

  • Main commands:
    • git
    • git add - Add file contents to the index
    • git am - Apply a series of patches from a mailbox
    • git archive - Create an archive of files from a named tree
    • git bisect Use binary search to find the commit that introduced a bug
    • git branch - List, create, or delete branches
    • git bundle - Move objects and refs by archive
    • git checkout - Switch branches or restore working tree files
    • git cherry-pick - Apply the changes introduced by some existing commits
    • git citool - Graphical alternative to git-commit
    • git clean - Remove un-tracked files from the working tree
    • git clone Clone a repository into a new directory
    • git commit - Record changes to the repository
    • git describe - Describe a commit using the most recent tag reachable from it
    • git diff - Show changes between commits, commit and working tree, etc
    • git fetch - Download objects and refs from another repository
    • git format-patch - Prepare patches for e-mail submission
    • git gc - Cleanup unnecessary files and optimize the local repository
    • git grep - Print lines matching a pattern
    • git gui - A portable graphical interface to Git
    • git init - Create an empty Git repository or reinitialize an existing one
    • git log - Show commit logs
    • git merge - Join two or more development histories together
    • git mv - Move or rename a file, a directory, or a symlink
    • git notes - Add or inspect object notes
    • git pull - Fetch from and integrate with another repository or a local branch
    • git push - Update remote refs along with associated objects
    • git rebase - Forward-port local commits to the updated upstream head
    • git reset - Reset current HEAD to the specified state
    • git revert - Revert some existing commits
    • git rm - Remove files from the working tree and from the index
    • git shortlog - Summarize git log output
    • git show - Show various types of objects
    • git stash - Stash the changes in a dirty working directory away
    • git status - Show the working tree status
    • git submodule - Initialize, update or inspect sub-modules
    • git tag - Create, list, delete or verify a tag object signed with GPG
    • git worktree - Manage multiple working trees
    • gitk - The Git repository browser
  • Ancillary Commands Manipulators:
  • Interrogators:
  • Interacting with Others: (interact with foreign SCM and with other people via patch over e-mail)

Low-Level "Plumbing" Commands:

Low-level commands are sufficient to support development of alternative commands. The following description divides the low-level commands into commands that manipulate objects (in the repository, index, and working tree), commands that interrogate and compare objects, and commands that move objects and references between repositories.

Links:

Book imageBooks:

"Version Control With Git"
by Jon Loeliger
ISBN #1449316387, O'Reilly Media; 2 edition (August 27, 2012)

Amazon.com
Distributed Version Control with Git [Kindle Edition]
Lars Vogel (Author)
A practical introduction into the Git version control system.

Amazon.com
Pro Git
Scott Chacon (Author)
Visual explanations of the git concepts and methodology.

Step-by-step ways to track, merge, and manage software projects, using Git.

Amazon.com