node-git-server logonode-git-server

Quick Start

A minimal server

Create a server that stores repositories under ./repos and accepts every push and fetch:

server.js
import { Git } from "@batchfy/node-git-server"
import path from "node:path"
 
const repos = new Git(path.resolve("./repos"), {
    autoCreate: true,
})
 
repos.on("push", (push) => {
    console.log(`push ${push.repo}/${push.commit} (${push.branch})`)
    push.accept()
})
 
repos.on("fetch", (fetch) => {
    console.log(`fetch ${fetch.repo}/${fetch.commit}`)
    fetch.accept()
})
 
repos.listen(7005, { type: "http" }, () => {
    console.log("node-git-server running at http://localhost:7005")
})

Start it:

$ node server.js
node-git-server running at http://localhost:7005

Push a repository

With autoCreate enabled, the target repository is created on first push. From any local repository:

$ git init
$ echo "hello" > README.md
$ git add README.md
$ git commit -m "first commit"
$ git push http://localhost:7005/my-project main

Output from the server side:

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 226 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To http://localhost:7005/my-project
 * [new branch]      main -> main

Clone it back

$ git clone http://localhost:7005/my-project
Cloning into 'my-project'...

What just happened

  1. git push first performs a GET /my-project/info/refs?service=git-receive-pack.
  2. Because the repository does not exist yet and autoCreate is true, the server runs git init --bare to create it.
  3. The push event fires — your handler calls push.accept() to allow it.
  4. The packfile is streamed to git-receive-pack, which writes the objects into the bare repository.

Next, learn how to react to each kind of request in Handling Events.