]> Untitled Git - git4ai.git/commitdiff
Initial commit
authorNikolay Shaplov <dhyan@nataraj.su>
Sun, 7 Jun 2026 03:45:07 +0000 (03:45 +0000)
committerNikolay Shaplov <dhyan@nataraj.su>
Sun, 7 Jun 2026 03:45:07 +0000 (03:45 +0000)
cgi/git4ai-cat-file.pl [new file with mode: 0755]
cgi/git4ai-log.pl [new file with mode: 0755]
cgi/git4ai-ls-tree.pl [new file with mode: 0755]
cgi/git4ai-show.pl [new file with mode: 0755]
cgi/git4ai.pl [new file with mode: 0755]
cgi/gitai-cat-file.pl [new symlink]
cgi/gitai-log.pl [new symlink]
cgi/gitai-ls-tree.pl [new symlink]
cgi/gitai-show.pl [new symlink]
cgi/gitai.pl [new symlink]
nginx-conf/git4ai [new file with mode: 0644]

diff --git a/cgi/git4ai-cat-file.pl b/cgi/git4ai-cat-file.pl
new file mode 100755 (executable)
index 0000000..6781098
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $GIT_ROOT = '/var/lib/git';
+
+my $repo    = $ENV{GIT_REPO};
+my $blob_id = $ENV{GIT_ID} || $ENV{GIT_BLOB_ID};
+
+$repo    =~ s{[^a-zA-Z0-9._-]}{}g;
+$blob_id =~ s{[^0-9a-f]}{}g;
+
+die unless $repo;
+die unless $blob_id;
+
+open(my $fh, '-|', 'git', "--git-dir=$GIT_ROOT/$repo",
+    'cat-file', 'blob', $blob_id)
+    or die "git cat-file failed: $!";
+
+# Читаем первые 8000 байт
+my $buf = '';
+read($fh, $buf, 8000);
+
+# Определяем тип по наличию нулевых байт. Так делает сам git
+my $is_binary = index($buf, "\x00") >= 0;
+my $ct = $is_binary
+    ? 'application/octet-stream'
+    : 'text/plain; charset=utf-8';
+
+binmode(STDOUT, ':raw');
+print "Content-Type: $ct\r\n";
+print "Cache-Control: no-store, no-cache, must-revalidate\r\n";
+print "\r\n";
+
+# Выводим буфер и остаток
+print $buf;
+while (read($fh, my $chunk, 65536)) {
+    print $chunk;
+}
+
+close($fh);
diff --git a/cgi/git4ai-log.pl b/cgi/git4ai-log.pl
new file mode 100755 (executable)
index 0000000..3564972
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $GIT_ROOT = '/var/lib/git';
+my $PER_PAGE = 20;
+my $BASE_URL = 'https://gitweb.nataraj.world';
+
+my $repo   = $ENV{GIT_REPO};
+my $branch = $ENV{GIT_BRANCH} // 'master';
+my $offset = int($ENV{GIT_OFFSET} // 0);
+my $nonce = $ENV{GIT_NONCE} || $ENV{REQUEST_ID};
+
+
+$repo   =~ s{[^a-zA-Z0-9._-]}{}g;
+$branch =~ s{[^a-zA-Z0-9._/\-]}{}g;
+$offset = 0 if $offset < 0;
+$nonce  =~ s{[^a-zA-Z0-9._-]}{}g;
+
+die unless $repo;
+die unless $branch;
+
+my $rand    = int(rand(1_000_000_000));
+my $git_dir = "$GIT_ROOT/$repo";
+
+print "Content-Type: text/html; charset=utf-8\r\n";
+print "Cache-Control: no-store, no-cache, must-revalidate\r\n";
+print "\r\n";
+
+open(my $fh, '-|', 'git', "--git-dir=$git_dir", 'log',
+    '--format=%H%x09%s%x09%an%x09%ad',
+    '--date=short',
+    "--skip=$offset",
+    "--max-count=$PER_PAGE",
+    "refs/heads/$branch")
+    or die "git failed: $!";
+
+my @commits;
+while (<$fh>) {
+    chomp;
+    my ($hash, $subject, $author, $date) = split /\t/, $_, 4;
+    push @commits, {
+        hash    => $hash,
+        subject => $subject,
+        author  => $author,
+        date    => $date,
+    };
+}
+close($fh);
+
+my $prev = $offset - $PER_PAGE; $prev = 0 if $prev < 0;
+my $next = $offset + $PER_PAGE;
+
+print <<HTML;
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>git log: $repo / $branch</title>
+</head>
+<body>
+<h2>git log: $repo / $branch (offset: $offset)</h2>
+Nonce: $nonce <br><br>
+HTML
+
+print "<a href=\"$BASE_URL/gitai-log/$repo/$branch/$prev/r$rand\">&larr; новее</a> &nbsp; "
+    if $offset > 0;
+print "<a href=\"$BASE_URL/gitai-log/$repo/$branch/$next/r$rand\">старее &rarr;</a>"
+    if @commits == $PER_PAGE;
+
+print "\n<table border='1' cellpadding='4'>\n";
+print "<tr><th>Diff</th><th>Дерево</th><th>Дата</th><th>Автор</th><th>Сообщение</th></tr>\n";
+
+for my $c (@commits) {
+    my $short    = substr($c->{hash}, 0, 8);
+    my $show_url = "$BASE_URL/gitai-show/$repo/$c->{hash}";
+    my $tree_url = "$BASE_URL/gitai-ls-tree/$repo/$c->{hash}/0/r$rand";
+    print "<tr>";
+    print "<td><a href=\"$show_url\">$short</a></td>";
+    print "<td><a href=\"$tree_url\">tree</a></td>";
+    print "<td>$c->{date}</td>";
+    print "<td>$c->{author}</td>";
+    print "<td>$c->{subject}</td>";
+    print "</tr>\n";
+}
+
+print "</table>\n";
+print "</body></html>\n";
diff --git a/cgi/git4ai-ls-tree.pl b/cgi/git4ai-ls-tree.pl
new file mode 100755 (executable)
index 0000000..137ed05
--- /dev/null
@@ -0,0 +1,83 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $GIT_ROOT = '/var/lib/git';
+my $PER_PAGE = 50;
+my $BASE_URL = 'https://gitweb.nataraj.world';
+
+my $repo   = $ENV{GIT_REPO};
+my $commit_id  = $ENV{GIT_ID} || $ENV{GIT_COMMIT_ID};
+my $offset = int($ENV{GIT_OFFSET} // 0);
+
+$repo =~ s{[^a-zA-Z0-9._-]}{}g;
+$commit_id  =~ s{[^0-9a-f]}{}g;
+$offset = 0 if $offset < 0;
+
+die unless $repo;
+die unless $commit_id;
+
+my $rand    = int(rand(1_000_000_000));
+my $git_dir = "$GIT_ROOT/$repo";
+
+print "Content-Type: text/html; charset=utf-8\r\n";
+print "Cache-Control: no-store, no-cache, must-revalidate\r\n";
+print "\r\n";
+
+# Показываем информацию о коммите
+open(my $log, '-|', 'git', "--git-dir=$git_dir", 'log',
+    '-1', '--format=%H %s (%an, %ad)', '--date=short', $commit_id)
+    or die "git log failed: $!";
+my $commit_info = <$log> // '';
+chomp $commit_info;
+close($log);
+
+# Получаем все файлы
+open(my $fh, '-|', 'git', "--git-dir=$git_dir", 'ls-tree',
+    '-r', '--long', $commit_id)
+    or die "git ls-tree failed: $!";
+
+my @files;
+while (<$fh>) {
+    chomp;
+    if (/^(\S+)\s+blob\s+([0-9a-f]{40})\s+(\S+)\t(.+)$/) {
+        push @files, { hash => $2, size => $3, name => $4 };
+    }
+}
+close($fh);
+
+my $total = scalar @files;
+my @page  = grep { defined } @files[$offset .. $offset + $PER_PAGE - 1];
+
+my $prev = $offset - $PER_PAGE; $prev = 0 if $prev < 0;
+my $next = $offset + $PER_PAGE;
+
+print <<HTML;
+<!DOCTYPE html>
+<html>
+<head><meta charset="utf-8">
+<title>git ls-tree: $repo / $commit_id</title>
+</head>
+<body>
+<h2>git ls-tree: $repo / $commit_id</h2>
+<p>$commit_info</p>
+<p>Файлов: $total, показаны $offset — @{[$offset + scalar @page]}</p>
+HTML
+
+print "<a href=\"$BASE_URL/gitai-ls-tree/$repo/$commit_id/$prev/r$rand\">&larr; выше</a> &nbsp; "
+    if $offset > 0;
+print "<a href=\"$BASE_URL/gitai-ls-tree/$repo/$commit_id/$next/r$rand\">ниже &rarr;</a>"
+    if $next < $total;
+
+print "\n<table border='1' cellpadding='4'>\n";
+print "<tr><th>Блоб</th><th>Размер</th><th>Файл</th></tr>\n";
+
+for my $f (@page) {
+    my $raw_url = "$BASE_URL/gitai-cat-file/$repo/$f->{hash}/r$rand";
+    my $short   = substr($f->{hash}, 0, 8);
+    printf "<tr><td><a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n",
+        $raw_url, $short, $f->{size}, $f->{name};
+}
+
+print "</table>\n";
+print "</body></html>\n";
diff --git a/cgi/git4ai-show.pl b/cgi/git4ai-show.pl
new file mode 100755 (executable)
index 0000000..0f9eb91
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $GIT_ROOT = '/var/lib/git';
+
+my $repo   = $ENV{GIT_REPO};
+my $commit = $ENV{GIT_ID} || $ENV{GIT_COMMIT};
+
+$repo   =~ s{[^a-zA-Z0-9._-]}{}g;
+$commit =~ s{[^0-9a-f]}{}g;
+
+die unless $repo;
+die unless $commit;
+
+print "Content-Type: text/plain; charset=utf-8\r\n";
+print "Cache-Control: no-store, no-cache, must-revalidate\r\n";
+print "\r\n";
+
+exec('git', "--git-dir=$GIT_ROOT/$repo", 'show', $commit);
diff --git a/cgi/git4ai.pl b/cgi/git4ai.pl
new file mode 100755 (executable)
index 0000000..2272d48
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+my $BASE_URL = 'https://gitweb.nataraj.world';
+my $LINKS    = 50;
+
+my $repo   = $ENV{GIT_REPO};
+my $branch = $ENV{GIT_BRANCH};
+
+$repo   =~ s{[^a-zA-Z0-9._-]}{}g;
+$branch =~ s{[^a-zA-Z0-9._/\-]}{}g;
+
+die unless $repo;
+die unless $branch;
+
+print "Content-Type: text/html; charset=utf-8\r\n";
+print "Cache-Control: no-store, no-cache, must-revalidate\r\n";
+print "\r\n";
+
+print <<HTML;
+<!DOCTYPE html>
+<html>
+<head><meta charset="utf-8">
+<title>gitai: $repo / $branch</title>
+</head>
+<body>
+
+<p>Это web entry point для ИИ для git репозитория $repo, ветки $branch.</p>
+
+<p>Коммит лог для ветки доступен по ссылке <a href="$BASE_URL/gitai1-log/$repo/$branch/0">вот этой</a> (страница не кешируется)</p>
+
+<p>Прочитав коммит лог, ты сможешь посмотреть на ls-tree для заданного коммита по ссылке вида https://gitweb.nataraj.world/gitai-ls-tree/$repo/[commit_id]</p>
+
+<p>Так же посмотреть на блобы упомянуте в ls-tree по ссылке вида https://gitweb.nataraj.world/gitai-raw/$repo/[blob_id]</p>
+
+<p>А так же на diff самих коммитов по ссылке вида https://gitweb.nataraj.world/gitai-show/[commit_id]</p>
+
+<p>Полный текст ссылок будет присутвовать на соответсвующих страницах, так что ограничений на fetch у тебя не будет</p>
+
+<p>Используй это знание для того чтобы получать ифнормацию из репозитория $repo/</p>
+
+
+HTML
+
+=cut
+<h2>Список одноразовых ссылок на незакешированный git log для репозитория $repo ветки $branch</h2>
+<ol>
+HTML
+
+for (1..$LINKS) {
+    my $rand = int(rand(1_000_000_000));
+    print "<li><a href=\"$BASE_URL/gitai-log/$repo/$branch/0/r$rand\">r$rand</a></li>\n";
+}
+=cut
+
+print "</ol></body></html>\n";
diff --git a/cgi/gitai-cat-file.pl b/cgi/gitai-cat-file.pl
new file mode 120000 (symlink)
index 0000000..7de7d62
--- /dev/null
@@ -0,0 +1 @@
+git4ai-cat-file.pl
\ No newline at end of file
diff --git a/cgi/gitai-log.pl b/cgi/gitai-log.pl
new file mode 120000 (symlink)
index 0000000..c765b9f
--- /dev/null
@@ -0,0 +1 @@
+git4ai-log.pl
\ No newline at end of file
diff --git a/cgi/gitai-ls-tree.pl b/cgi/gitai-ls-tree.pl
new file mode 120000 (symlink)
index 0000000..9489a5d
--- /dev/null
@@ -0,0 +1 @@
+git4ai-ls-tree.pl
\ No newline at end of file
diff --git a/cgi/gitai-show.pl b/cgi/gitai-show.pl
new file mode 120000 (symlink)
index 0000000..e049d8b
--- /dev/null
@@ -0,0 +1 @@
+git4ai-show.pl
\ No newline at end of file
diff --git a/cgi/gitai.pl b/cgi/gitai.pl
new file mode 120000 (symlink)
index 0000000..4ab2b52
--- /dev/null
@@ -0,0 +1 @@
+git4ai.pl
\ No newline at end of file
diff --git a/nginx-conf/git4ai b/nginx-conf/git4ai
new file mode 100644 (file)
index 0000000..f18bfdf
--- /dev/null
@@ -0,0 +1,233 @@
+map $uri $git4ai_script {
+
+    ~^/git4ai-show/     /srv/cgi/git4ai-show.pl;
+    ~^/git4ai-cat-file/ /srv/cgi/git4ai-cat-file.pl;
+    ~^/git4ai-log/      /srv/cgi/git4ai-log.pl;
+    ~^/git4ai-ls-tree/  /srv/cgi/git4ai-ls-tree.pl;
+    ~^/git4ai/          /srv/cgi/git4ai.pl;
+}
+
+server {
+  listen 80;
+
+  location /index.cgi {
+    root /usr/share/gitweb/;
+    include fastcgi_params;
+    gzip off;
+
+    fastcgi_param LANG "en_US.UTF-8";
+    fastcgi_param LC_ALL "en_US.UTF-8";
+    fastcgi_param PERL_UNICODE "SD";  # S=stdin/stdout UTF-8, D=@ARGV UTF-8
+
+    fastcgi_param SCRIPT_NAME $uri;
+    fastcgi_param GITWEB_CONFIG /etc/gitweb.conf;
+    fastcgi_pass  unix:/var/run/fcgiwrap.socket;
+
+    # Не кешируем. Иначе колд айай начинает видеть старые версии вместо актуальных
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    add_header Pragma "no-cache" always;
+    expires -1;
+  }
+
+  location / {
+    root /usr/share/gitweb/;
+    index index.cgi;
+
+    # Не кешируем. Иначе колд айай начинает видеть старые версии вместо актуальных
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    add_header Pragma "no-cache" always;
+    expires -1;
+  }
+
+
+  location /gitweb3/index.cgi {
+    root /usr/share/gitweb/;
+    include fastcgi_params;
+    gzip off;
+
+    fastcgi_param LANG "en_US.UTF-8";
+    fastcgi_param LC_ALL "en_US.UTF-8";
+    fastcgi_param PERL_UNICODE "D";  # S=stdin/stdout UTF-8 (убрано), D=@ARGV UTF-8
+
+    fastcgi_param SCRIPT_NAME $uri;
+    fastcgi_param SCRIPT_FILENAME /usr/share/gitweb/index.cgi;
+    
+    fastcgi_param GITWEB_CONFIG /etc/gitweb.conf;
+    fastcgi_pass  unix:/var/run/fcgiwrap.socket;
+
+    # Не кешируем. Иначе колд айай начинает видеть старые версии вместо актуальных
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    add_header Pragma "no-cache" always;
+    expires -1;
+  }
+
+  location /gitweb3 {
+    root /usr/share/gitweb/;
+    #    index index.cgi;
+
+    try_files $uri /gitweb3/index.cgi$is_args$args;
+
+    # Не кешируем. Иначе колд айай начинает видеть старые версии вместо актуальных
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    add_header Pragma "no-cache" always;
+    expires -1;
+  }
+
+
+
+location ~ "^/raw/([^/]+)/([0-9a-f]{4,40})$" {
+    rewrite "^/raw/([^/]+)/([0-9a-f]{4,40})$" /?p=$1&a=blob_plain&h=$2 break;
+    proxy_pass http://127.0.0.1:80;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+
+location = /raw/ {
+    default_type text/plain;
+    return 200 "https://gitweb.nataraj.world/raw/articles.git/\n";
+    add_header Cache-Control "no-store" always;
+}
+
+
+  # Временная копия на то время пока не протух кеш
+location /gitweb2/ {
+    proxy_pass http://127.0.0.1:80/;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    add_header Pragma "no-cache" always;
+    expires -1;
+}
+
+
+# Если без nonce'а добавляем nonce.
+location ~ "^/git4ai-log/([^/]+)/([^/]+)/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/git4ai-log/$1/$2/$3/$4/$request_id;
+    add_header Cache-Control "no-store" always;
+}
+
+location ~ "^/git4ai-log/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/git4ai-log/$1/$2/-/0;
+    add_header Cache-Control "no-store" always;
+}
+
+location ~ "^/git4ai-log/([^/]+)/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/git4ai-log/$1/$2/-/$3;
+    add_header Cache-Control "no-store" always;
+}
+
+#                           repo             branch             id                 offset     nonce
+location ~ "^/git4ai[^/]*/([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+|-)/([0-9a-f]{4,40}|-)/([0-9]+|-)(?:/([a-zA-Z0-9]+))?$" {
+    set $git_repo    $1;
+    set $git_branch  $2;
+    set $git_id      $3;
+    set $git_offset  $4;
+    set $git_nonce   $5;
+    
+    # Должно идти после того как все $N переменные использованы. Так как map $git4ai_scrit их портит
+    fastcgi_param SCRIPT_FILENAME $git4ai_script;
+    fastcgi_param GIT_REPO    $git_repo;
+    fastcgi_param GIT_BRANCH  $git_branch;
+    fastcgi_param GIT_ID      $git_id;
+    fastcgi_param GIT_OFFSET  $git_offset;
+    fastcgi_param GIT_NONCE   $git_nonce;
+
+    fastcgi_pass unix:/var/run/fcgiwrap.socket;
+    include fastcgi_params;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+location ~ "^/gitai1/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/gitai/$1/$2/r$request_id;
+    add_header Cache-Control "no-store" always;
+}
+
+location ~ "^/gitai/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/gitai/$1/$2/r$request_id;
+    add_header Cache-Control "no-store" always;
+}
+
+location ~ "^/gitai/([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)/[a-zA-Z0-9]+$" {
+    fastcgi_pass unix:/var/run/fcgiwrap.socket;
+    fastcgi_param SCRIPT_FILENAME /srv/cgi/gitai.pl;
+    fastcgi_param GIT_REPO        $1;
+    fastcgi_param GIT_BRANCH      $2;
+    include fastcgi_params;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+location ~ "^/gitai-log/([^/]+)/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/gitai-log/$1/$2/$3/$request_id;
+    add_header Cache-Control "no-store" always;
+}
+
+location ~ "^/gitai1-log/([^/]+)/([^/]+)/([^/]+)$" {
+    return 302 https://gitweb.nataraj.world/gitai-log/$1/$2/$3/$request_id;
+    add_header Cache-Control "no-store" always;
+}
+
+location ~ "^/gitai-log/([a-zA-Z0-9._-]+)/([a-zA-Z0-9._-]+)/([0-9]+)/[a-zA-Z0-9]+$" {
+    fastcgi_pass unix:/var/run/fcgiwrap.socket;
+    fastcgi_param SCRIPT_FILENAME /srv/cgi/gitai-log.pl;
+    fastcgi_param GIT_REPO        $1;
+    fastcgi_param GIT_BRANCH      $2;
+    fastcgi_param GIT_OFFSET      $3;
+    fastcgi_param REQUEST_ID     $request_id;
+    include fastcgi_params;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+location ~ "^/gitai-ls-tree/([a-zA-Z0-9._-]+)/([0-9a-f]{4,40})/([0-9]+)(?:/[a-zA-Z0-9]+)?$" {
+    fastcgi_pass unix:/var/run/fcgiwrap.socket;
+    fastcgi_param SCRIPT_FILENAME /srv/cgi/gitai-ls-tree.pl;
+    fastcgi_param GIT_REPO        $1;
+    fastcgi_param GIT_COMMIT_ID   $2;
+    fastcgi_param GIT_OFFSET      $3;
+    include fastcgi_params;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+location ~ "^/gitai-show/([^/]+)/([0-9a-f]{4,40})(?:/[a-zA-Z0-9]+)?$" {
+    fastcgi_pass unix:/var/run/fcgiwrap.socket;
+    fastcgi_param SCRIPT_FILENAME /srv/cgi/gitai-show.pl;
+    fastcgi_param GIT_REPO        $1;
+    fastcgi_param GIT_COMMIT      $2;
+    include fastcgi_params;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+location ~ "^/gitai-cat-file/([^/]+)/([0-9a-f]{4,40})(?:/[a-zA-Z0-9]+)?$" {
+    fastcgi_pass unix:/var/run/fcgiwrap.socket;
+    fastcgi_param SCRIPT_FILENAME /srv/cgi/gitai-cat-file.pl;
+    fastcgi_param GIT_REPO        $1;
+    fastcgi_param GIT_BLOB_ID     $2;
+    include fastcgi_params;
+    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+    expires -1;
+}
+
+#location ~ "^/gitai-raw/([^/]+)/([0-9a-f]{4,40})(?:/r[0-9]+)?$" {
+#    rewrite "^/gitai-raw/([^/]+)/([0-9a-f]{4,40})(?:/r[0-9]+)?$" /?p=$1&a=blob_plain&h=$2 break;
+#    proxy_pass http://127.0.0.1:80;
+#    add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+#    expires -1;
+#}
+
+
+  location ~ ^/git(/.*) {
+        fastcgi_pass unix:/var/run/fcgiwrap.socket;
+        fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
+        fastcgi_param GIT_PROJECT_ROOT /var/lib/git;
+        fastcgi_param GIT_HTTP_EXPORT_ALL "";
+        fastcgi_param PATH_INFO $1;
+        include fastcgi_params;    
+  }
+
+  location /hooks {
+    proxy_pass http://127.0.0.1:9000/hooks;
+  }
+}