Search code examples
gitolite

Is it possible to modify git config options for wild respos without manually editing the gitolite.conf file?


Suppose I have pushed to and configured the wild repo foo/bar.

If I want to add a mailing list option to this repo, one way is to add the following to my gitolite.conf file.

repo foo/ba[r]
    config hooks.mailinglist = foo@bar.com

However, this requires that I have access to the gitolite.conf which is part of gitolite-admin repository.

Is there any way an ordinary user could make this modification, without access to the admin configuration file?

Note that I have already perused the documentation to no avail.


Solution

  • I got the following answer from the gitolite mailing list. However, this answer does not handle wild cards in GIT_CONFIG_KEYS, so I modified it to handle this the same way gitolite does.

    It sufficed the insert the following inside commands/config and then add config to the list of enabled options in .gitolite.rc.

    #!/bin/bash
    
    # Usage:    ssh git@host config <repo> --get <name>
    #           ssh git@host config <repo> --set <name> <value>
    #           ssh git@host config <repo> --unset <name>
    #
    # Set a "git config" option on a repo. You must be an owner of the
    # repo, and the config option name must be allowed by the gitolite.rc
    # configuration.
    
    die() { echo "$@" >&2; exit 1; }
    usage() { perl -lne 'print substr($_, 2) if /^# Usage/../^$/' < $0; exit 1; }
    [ -z "$1" ] && usage
    [ "$1" = "-h" ] && usage
    [ -z "$GL_USER" ] && die GL_USER not set
    
    repo="$1"; shift
    
    gitolite owns "$repo" || die "repository '$repo' missing or you do not own it"
    cd `gitolite query-rc GL_REPO_BASE`/"$repo".git || die "missing repository '$1'";
    
    case $1 in
    --get)  action='--get'
            shift
            [ "$#" -eq 1 ] || usage
            ;;
    --set)  action='--set'
            shift
            [ "$#" -gt 1 ] || usage
            ;;
    --unset)
            action='--unset'
            shift
            [ "$#" -eq 1 ] || usage
            ;;
    *)      if [ "$#" -eq 1 ]
            then action='--get'
            else action='--set'
            fi
            ;;
    esac
    
    name="$1"; shift
    
    ALLOWED_CONFIG=$(gitolite query-rc GIT_CONFIG_KEYS)
    
    export ALLOWED_CONFIG                                             
    export name                                                       
    
    deny=$(perl -e '                                                  
         my @validkeys = split( " ", ( $ENV{ALLOWED_CONFIG} || "" ) );
         my @matched = grep { $ENV{name} =~ /^$_$/i } @validkeys;     
         if (@matched < 1) {print "Denied\n";}')                      
    
    if [[ -n "$deny" ]]; then                                         
            die "config option '$name' not allowed by gitolite.rc"    
            exit 1                                                    
    fi 
    
    
    
    # there is not much need to sanitise the input; by default all
    # arguments to commands are restricted to these: -0-9a-zA-Z._\@/+ :,\%=
    # (see Gitolite::Rc.pm, the variable is $REMOTE_COMMAND_PATT) however
    # for safety we will check the value for consistency with $UNSAFE_PATT
    
    UNSAFE_PATT='.*[`~#\$\&()|;<>]'
    
    case $action in
    --set)  if expr "$*" : "$UNSAFE_PATT" >/dev/null
            then
                    die "value '$*' contains unsafe characters"
            else
                    git config "$name" "$*"
            fi
            ;;
    *)      git config $action "$name"
            ;;
    esac