Crie seu própio Github!

Introdução

Hoje em dia o Github certamente é a maior plataforma de hospedagem de código do mundo. Mas existem algumas alternativas notáveis como o Gitlab e o BitBucket. Além de algumas alternativas completamente open source (além do GitLab), como o Gitea.

Mas e que tal criar a sua própia alternativa ao Github? Provavelmente você não vai querer reinventar a roda, mas pode ser um projetinho interessante, não acha?

Aqui nos vamos utilizar Javascript e Nodejs, utilizando a biblioteca node-git-server, para não termos que nos preocupar de como é a implemetação de um servidor git (mas caso você queria, pode dar uma olhada na documentação oficial do git). Você pode tentar procurar implementações na sua linguagem favorita, em encontrei algumas em Python. Uma que utiliza Flask e outra que utiliza FastAPI (nesse caso são implementações, não bibliotecas que abstream a utilização. Mas verifiquei o código fonte e ambas são bem simples de entender e modificar). Também vou considerar que você já tem o conhecimento básico de Javascript, Nodejs e Git.

Instalação

Você vai precisar do Nodejs e do Git. Nada mais.

Criação do projeto

Nosso servidor vai ter o seguinte código:

import { Git }  from "node-git-server"
import { join } from "path"

const repos = new Git(join(__dirname, "./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.commit}`)
  fetch.accept()
})

repos.listen(8000, { type: "http" }, () => {
  console.log("Running at http://localhost:8000")
})

Pronto! já temos um servidor de git rodando, você pode testar clonando um repositório:

>> git clone http://localhost:8000/test
Cloning into 'test'...
warning: You appear to have cloned an empty repository.

Como passamos o parâmetro autoCreate: true na criação do objeto repos, ele automaticamente irá criar o repositório caso ele não exista.

Podemos adicionar autenticação ao nosso servidor, passando o parâmetro authenticate:

const repos = new Git(join(__dirname, "./repos"), {
  autoCreate: true,
  authenticate: ({ type, user }, next) => {
    if (type == "push") {
      user((username, password) => {
        if (username === "username" && password === "password") {
          next()
        } else {
          next(new Error("Invalid username or password"))
        }
      })
    } else {
      next()
    }
  }
})

Agora, se rodarmos novamente, quando pedirmos para fazer um push, ele irá pedir o usuário e a senha:

>> git push
Username for 'http://localhost:8000': username
Password for 'http://username@localhost:8000':
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 210 bytes | 210.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To http://localhost:8000/test
 * [new branch]      main -> main

Nesse caso, ele apenas vai verificar se o usuário e senha correspondem respectivamente a "username" e "password", mas você costumizar a autenticação como quiser, por exemplo verificando se o usuário existe em um banco de dados, e pedir a autenticação para todas as ações (clone, pull, etc), para fazer um repositório 100% privado.

O node-git-server tem mais algumas funções como o envio de logs para o cliente, como você pode conferir na documentação.


Pro hoje é isso, isso é apenas o básico, talvez eu possa fazer fazer uma série criando de fato um clone do Github, com interface gráfica e várias das funcionalidades...

Qualquer dúvida ou sugestão podem colocar nos comentários ;)

Muito bomm, parabéns, há 2 dias atrás eu fiz uma alternativa do meu Google Drive, ficou muito bom. E mais uma vez, parabéns!

Legal! Você já publicou osbre esse projeto aqui no Tabnews?

Projeto interessante, eu gostaria muito de ver como seria o andamento desse projeto

E caso continue desenvolvendo eu gostaria muito de acompanhar o desenvolvimento de perto, estou estudando programação há 1 mês, então seria mais acompanhamento pra fins de estudo mesmo.
Vou prosseguir com esse projeto, aguade as novas publicações ;)

Muito legal a iniciativa! Faz sim a série. Vai ser massa.

Vou fazer isso! Pretendo fazer um clone básico do github com express e react

Massa demais! Inclusive faça essa série sim, será de grande valor!