Node.js Git Server

1.0.0 · active · verified Sun Apr 19

node-git-server is a highly configurable Git server implemented in Node.js, designed for embedding or standalone deployment within a Node.js environment. The project adheres to a 'zero dependency footprint' philosophy, aiming to keep its core lean and efficient. Its current stable version is 1.0.0, released recently after an extensive beta phase. Key differentiators include its programmatic control over Git operations, extensive configurability for authentication and authorization, and its origin as a hard fork of the well-established `pushover` library. The library migrated to TypeScript starting with version 1.0.0-beta.1, enhancing type safety and developer experience. It now requires Node.js version 16 or newer, aligning with modern Node.js LTS releases. The project shows an active development and release cadence, having frequently updated through its beta cycle to reach a stable 1.0.0 release.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart code demonstrates how to set up a basic configurable Git server using node-git-server. It initializes a Git server instance, defines a directory for repositories, implements a simple username/password authentication mechanism, and handles push/fetch events. The server listens on a specified port, allowing users to clone and push to repositories managed by this instance.

import { GitServer } from 'node-git-server';
import path from 'path';
import fs from 'fs';

const REPOS_DIR = path.resolve(process.env.GIT_REPOS_DIR ?? './tmp/repos');

// Ensure the repository directory exists
if (!fs.existsSync(REPOS_DIR)) {
  fs.mkdirSync(REPOS_DIR, { recursive: true });
}

const git = new GitServer(REPOS_DIR, {
  autoCreate: true, // Automatically create repositories on first push
  authenticate: (type, repository, username, password, callback) => {
    console.log(`Authentication attempt: ${type} for ${repository} by ${username}`);
    // In a real application, validate username and password against a database
    if (username === 'gituser' && password === 'gitpass') {
      console.log('Authentication successful.');
      return callback(null, true); // Authentication successful
    }
    console.log('Authentication failed.');
    return callback(new Error('Authentication failed'), false); // Authentication failed
  },
  authorize: (type, repository, username, callback) => {
    console.log(`Authorization attempt: ${type} for ${repository} by ${username}`);
    // In a real application, check permissions based on user and repository
    if (username === 'gituser') {
      console.log('Authorization successful.');
      return callback(null, true); // Authorization successful
    }
    console.log('Authorization failed.');
    return callback(new Error('Authorization failed'), false); // Authorization failed
  },
});

git.on('push', (push) => {
  console.log(`Push event: ${push.repo}/${push.commit} by ${push.branch}`);
  push.accept(); // Accept the push
});

git.on('fetch', (fetch) => {
  console.log(`Fetch event: ${fetch.repo} by ${fetch.branch}`);
  fetch.accept(); // Accept the fetch
});

const PORT = parseInt(process.env.GIT_SERVER_PORT ?? '7000', 10);

git.listen(PORT, () => {
  console.log(`node-git-server running on port ${PORT}`);
  console.log(`Serving repositories from: ${REPOS_DIR}`);
  console.log(`Try cloning: git clone http://localhost:${PORT}/my-repo.git`);
});

// Handle process exit to close server gracefully
process.on('SIGINT', () => {
  console.log('Shutting down git server...');
  git.close(() => {
    console.log('Git server closed.');
    process.exit(0);
  });
});

view raw JSON →