Autor: tutorial preparado para Pablo Murad
Data: 2026-06-12
Objetivo: explicar o que é SourceHut/sr.ht, como ele funciona, como configurar SSH, criar repositórios, subir código, clonar projetos, usar hut, CI/builds, Pages e o básico do fluxo por email.
1. O que é SourceHut?
SourceHut, também escrito como sr.ht, é uma plataforma de desenvolvimento de software. Ele parece com GitHub/GitLab/Codeberg em alguns pontos, mas a filosofia é diferente.
Ele é uma suíte modular de serviços:
| Serviço | Função |
|---|---|
git.sr.ht | Hospedagem de repositórios Git |
hg.sr.ht | Hospedagem de repositórios Mercurial |
builds.sr.ht | CI/CD, builds e automações |
todo.sr.ht | Tarefas, tickets e bugs |
lists.sr.ht | Listas de email e revisão de patches |
man.sr.ht | Documentação/wiki em Markdown versionada |
paste.sr.ht | Snippets/pastes de código |
pages.sr.ht / srht.site | Hospedagem de sites estáticos |
meta.sr.ht | Conta, chaves SSH, tokens e segurança |
hub.sr.ht | Página que agrupa recursos de um projeto |
A página oficial apresenta o SourceHut como uma suíte open source, sem anúncios/tracking, que funciona sem JavaScript, com Git/Mercurial, CI, listas de email, tickets e páginas estáticas.
Resumo honesto: SourceHut é uma forge para quem gosta de Git, terminal, software livre, email, automação e ferramentas simples. Não é um GitHub com outra pele.
2. Diferença entre SourceHut e GitHub
No GitHub, o fluxo típico é:
- criar repositório;
- subir código;
- abrir issue;
- fazer fork;
- abrir pull request;
- revisar pelo navegador.
No SourceHut, o fluxo cultural é mais próximo de projetos clássicos de software livre:
- clonar o projeto;
- trabalhar localmente;
- gerar commit/patch;
- enviar patch por email/lista;
- discutir em thread;
- mantenedor aplica o patch.
Mas calma: para seus projetos pessoais você pode usar como Git remoto normal:
git clone ...
git add .
git commit -m "mensagem"
git push
git pull
A parte de email é mais importante quando você quer contribuir com projetos de terceiros que usam listas de email.
3. Endereços que você precisa decorar
https://sr.ht/ -> painel geral
https://meta.sr.ht/ -> conta, SSH, tokens, segurança
https://git.sr.ht/ -> repositórios Git
https://builds.sr.ht/ -> CI/builds
https://todo.sr.ht/ -> tarefas/tickets
https://lists.sr.ht/ -> listas de email
https://man.sr.ht/ -> documentação/wiki
https://paste.sr.ht/ -> snippets
https://pages.sr.ht/ -> páginas estáticas
Para começar, foque só em:
meta.sr.ht + git.sr.ht
4. Como funciona o nome dos repositórios
No SourceHut, usuários aparecem com ~ antes do nome.
Exemplo fictício:
~pablo
Um repositório Git fica assim:
https://git.sr.ht/~pablo/meu-projeto
Via SSH:
git@git.sr.ht:~pablo/meu-projeto
Essa sintaxe com ~usuario é normal.
5. Configurando SSH
Para subir código com conforto, configure chave SSH.
5.1. Ver se você já tem uma chave
ls -la ~/.ssh
Procure por:
id_ed25519
id_ed25519.pub
id_rsa
id_rsa.pub
Prefira ed25519 hoje.
5.2. Criar chave SSH
ssh-keygen -t ed25519 -C "seu-email@example.com"
Aceite o caminho padrão:
~/.ssh/id_ed25519
Arquivos gerados:
~/.ssh/id_ed25519 -> chave privada, nunca compartilhe
~/.ssh/id_ed25519.pub -> chave pública, pode cadastrar no SourceHut
5.3. Copiar a chave pública
cat ~/.ssh/id_ed25519.pub
Copie a linha inteira, parecida com:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... seu-email@example.com
5.4. Cadastrar no SourceHut
Entre em:
https://meta.sr.ht/
Procure a área de SSH keys e cole a chave pública.
Atenção: nunca cole id_ed25519. Só cole id_ed25519.pub.
6. Testando o SSH
Rode:
ssh git@git.sr.ht
Você provavelmente não vai receber um shell interativo. Isso é normal. A ideia é só testar autenticação.
Se aparecer:
Permission denied (publickey)
Corrija com:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh git@git.sr.ht
Se continuar falhando, sua chave pública provavelmente não foi cadastrada corretamente no meta.sr.ht.
7. Criando repositório pelo navegador
- Entre em
https://git.sr.ht/. - Faça login.
- Clique para criar um novo repositório.
- Escolha nome, descrição e visibilidade.
- Crie.
Visibilidades comuns:
| Visibilidade | Uso recomendado |
|---|---|
public | projeto público/open source |
unlisted | acessível por link, mas não listado publicamente |
private | privado |
Recomendação direta:
- projeto público:
public; - protótipo compartilhável por link:
unlisted; - código pessoal, cliente, bot, deploy, automação interna:
private.
Mesmo em repositório privado, não suba .env, token, chave privada, dump de banco ou senha.
8. Criando repositório pelo terminal com hut
hut é a CLI para SourceHut. Ela interage com Git, Mercurial, builds, tickets, listas, páginas, pastes e outros serviços.
8.1. Instalar hut
No Arch:
sudo pacman -S hut
No Alpine:
sudo apk add hut
No Debian/Ubuntu, verifique se existe pacote disponível:
apt search hut
Se não houver pacote adequado, instale conforme a documentação/projeto do hut.
8.2. Inicializar
hut init
Ele pedirá um token OAuth/API. Crie no meta.sr.ht com as permissões necessárias.
8.3. Listar repositórios
hut git list
8.4. Criar repositório
Público:
hut git create meu-projeto -v public
Não listado:
hut git create meu-projeto -v unlisted
Privado:
hut git create meu-projeto -v private
Com descrição:
hut git create meu-projeto -v private -d "Descrição curta do projeto"
Criar e já clonar, se sua versão suportar:
hut git create meu-projeto --clone
ou:
hut git create meu-projeto -c
9. Subindo um projeto novo para o SourceHut
Imagine que você criou o repositório meu-projeto em git.sr.ht.
Entre na pasta local:
mkdir meu-projeto
cd meu-projeto
Inicialize Git:
git init
Crie README:
echo "# Meu Projeto" > README.md
Crie .gitignore básico:
cat > .gitignore <<'GITIGNORE'
node_modules/
.env
.venv/
__pycache__/
*.pyc
.DS_Store
.idea/
.vscode/
dist/
build/
*.log
GITIGNORE
Faça commit:
git add .
git commit -m "Initial commit"
Se o Git reclamar de nome/email:
git config --global user.name "Pablo Murad"
git config --global user.email "seu-email@example.com"
Defina branch principal:
git branch -M main
Adicione remoto SSH:
git remote add origin git@git.sr.ht:~pablo/meu-projeto
Envie:
git push -u origin main
Pronto. Código no SourceHut.
10. Clonando um repositório
10.1. Clone via HTTPS
Bom para projeto público:
git clone https://git.sr.ht/~usuario/repositorio
Exemplo:
git clone https://git.sr.ht/~pablo/meu-projeto
10.2. Clone via SSH
Melhor para seus projetos e privados:
git clone git@git.sr.ht:~usuario/repositorio
Exemplo:
git clone git@git.sr.ht:~pablo/meu-projeto
10.3. Clone com hut
hut git clone ~pablo/meu-projeto
Ou:
hut git clone https://git.sr.ht/~pablo/meu-projeto
O hut git clone pode configurar detalhes úteis para contribuição por email/patch.
11. Fluxo diário básico
Dentro do projeto:
git status
git pull
git add .
git commit -m "Descreve a alteração"
git push
Ver remotos:
git remote -v
Trocar remoto:
git remote set-url origin git@git.sr.ht:~pablo/meu-projeto
12. Migrando projeto de GitHub/GitLab/Codeberg para SourceHut
12.1. Se você já tem a pasta local
cd meu-projeto
git remote -v
git remote set-url origin git@git.sr.ht:~pablo/meu-projeto
git push -u origin main
Se usa master:
git push -u origin master
Enviar todas as branches:
git push --all origin
Enviar tags:
git push --tags origin
12.2. Migração espelhada
git clone --mirror https://github.com/usuario/repositorio.git
cd repositorio.git
git remote set-url origin git@git.sr.ht:~pablo/repositorio
git push --mirror
Cuidado com --mirror. Ele espelha tudo e pode sobrescrever refs remotas. Use só quando souber o impacto.
13. README decente
Use README.md.
Modelo mínimo:
# Nome do Projeto
Descrição curta do que o projeto faz.
## Instalação
```bash
comando de instalação
```
## Uso
```bash
comando de uso
```
## Configuração
Copie `.env.example` para `.env` e ajuste as variáveis.
## Licença
MIT
README bom explica:
- o que é;
- como instalar;
- como rodar;
- como configurar;
- exemplos;
- licença;
- status do projeto.
14. Branch main ou master
Veja branch atual:
git branch
Renomeie para main:
git branch -M main
git push -u origin main
Se precisar ajustar branch padrão no SourceHut, faça pelo painel do repositório ou pelo hut, se suportado pela sua versão:
hut git update ~pablo/meu-projeto --default-branch main
15. todo.sr.ht: issues/tarefas
No SourceHut, o sistema de tarefas é separado:
https://todo.sr.ht/
Ele não tenta ser uma rede social de issues. É mais seco e objetivo.
Para projetos pequenos, você pode começar com:
TODO.md
Depois, se crescer, use todo.sr.ht.
16. hub.sr.ht: página de projeto
hub.sr.ht agrupa os recursos de um projeto:
Projeto: macombot
- git.sr.ht/~pablo/macombot
- todo.sr.ht/~pablo/macombot
- lists.sr.ht/~pablo/macombot-devel
- man.sr.ht/~pablo/macombot
Para começo, ignore. Domine git.sr.ht primeiro.
17. builds.sr.ht: CI com .build.yml
SourceHut usa arquivo .build.yml.
Exemplo mínimo:
image: alpine/latest
packages:
- python3
sources:
- https://git.sr.ht/~pablo/meu-projeto
tasks:
- test: |
cd meu-projeto
python3 --version
Projeto Node:
image: alpine/latest
packages:
- nodejs
- npm
sources:
- https://git.sr.ht/~pablo/meu-projeto
tasks:
- install: |
cd meu-projeto
npm install
- test: |
cd meu-projeto
npm test
Projeto Python:
image: debian/stable
packages:
- python3
- python3-pip
sources:
- https://git.sr.ht/~pablo/meu-projeto
tasks:
- test: |
cd meu-projeto
python3 -m pip install -r requirements.txt
python3 -m pytest
Não comece pelo CI. Primeiro faça clone, push e pull funcionarem.
18. pages.sr.ht: site estático
Você pode publicar site em:
https://seuusuario.srht.site/
Fluxo típico:
- código do site em
git.sr.ht; .build.ymlgera os arquivos estáticos;hut pages publishpublica o pacote.
Exemplo genérico:
image: alpine/edge
packages:
- hut
oauth: pages.sr.ht/PAGES:RW
environment:
site: pablo.srht.site
sources:
- https://git.sr.ht/~pablo/site
tasks:
- package: |
cd site
tar -cvz . > ../site.tar.gz
- upload: |
hut pages publish -d $site site.tar.gz
Com Hugo:
image: alpine/edge
packages:
- hut
- hugo
oauth: pages.sr.ht/PAGES:RW
environment:
site: pablo.srht.site
sources:
- https://git.sr.ht/~pablo/site
tasks:
- build: |
cd site
hugo
- package: |
cd site
tar -C public -cvz . > ../site.tar.gz
- upload: |
hut pages publish -d $site site.tar.gz
19. Colaboração por patch/email
Este é o ponto que mais diferencia SourceHut.
Fluxo conceitual:
git clone https://git.sr.ht/~autor/projeto
cd projeto
git checkout -b minha-mudanca
# edite arquivos
git add .
git commit -m "Corrige X"
git format-patch -1
Isso gera um arquivo parecido com:
0001-Corrige-X.patch
Depois você envia para a lista do projeto, geralmente com git send-email.
Mas para seus próprios repositórios, não complique agora. Aprenda nesta ordem:
- Git remoto normal.
- SSH.
hut.- README e
.gitignore. - Builds.
- Pages.
- Patches por email.
20. Repositório privado
Criar:
hut git create meu-projeto-secreto -v private
Adicionar remoto:
git remote add origin git@git.sr.ht:~pablo/meu-projeto-secreto
Enviar:
git push -u origin main
Clonar:
git clone git@git.sr.ht:~pablo/meu-projeto-secreto
Ver comandos de permissão/ACL disponíveis:
hut git acl --help
21. Comandos essenciais
Criar local e subir:
mkdir meu-projeto
cd meu-projeto
git init
echo "# Meu Projeto" > README.md
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin git@git.sr.ht:~pablo/meu-projeto
git push -u origin main
Clonar:
git clone git@git.sr.ht:~pablo/meu-projeto
Atualizar:
git pull
git add .
git commit -m "Minha alteração"
git push
Listar repositórios com hut:
hut git list
Criar repositório privado:
hut git create meu-projeto -v private
22. Erros comuns
Permission denied (publickey)
SSH não autenticou.
Tente:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh git@git.sr.ht
Confira a chave no meta.sr.ht.
Repository not found
Cheque:
git remote -v
Formato SSH correto:
git@git.sr.ht:~usuario/repositorio
Formato HTTPS correto:
https://git.sr.ht/~usuario/repositorio
Push rejeitado por non-fast-forward
git pull --rebase
git push
Não use git push --force sem entender o impacto.
Subiu segredo por acidente
- Revogue token/senha imediatamente.
- Remova do Git.
- Adicione ao
.gitignore. - Se necessário, reescreva histórico.
Remover .env do commit atual:
git rm --cached .env
echo ".env" >> .gitignore
git add .gitignore
git commit --amend
git push --force-with-lease
Mesmo assim: revogue a credencial. Apagar do Git não garante segurança.
23. Organização recomendada para seus projetos
Pelo tipo de coisa que você costuma fazer — bots, automações, compêndios, sistemas, temas, scripts e experimentos — eu organizaria assim:
Públicos
- temas visuais;
- scripts genéricos;
- ferramentas pequenas;
- projetos que servem como portfolio;
- bibliotecas sem segredo.
Unlisted
- protótipos;
- zines em desenvolvimento;
- compêndios em revisão;
- experimentos que você quer compartilhar por link.
Privados
- bots com tokens;
- automações de cliente;
- integrações com banco;
- scripts de servidor;
- projetos com dados internos;
- qualquer coisa com configuração sensível.
E repito porque é onde gente boa faz besteira: .env fora do Git.
24. Estrutura mínima boa
meu-projeto/
├── README.md
├── LICENSE
├── .gitignore
├── .env.example
├── src/
├── docs/
└── scripts/
Exemplo de .env.example:
OPENAI_API_KEY=coloque_sua_chave_aqui
DATABASE_URL=mysql://usuario:senha@host/banco
Suba .env.example, não .env.
25. Exemplo completo: Python
mkdir exemplo-python
cd exemplo-python
git init
cat > README.md <<'README'
# Exemplo Python
Projeto de teste hospedado no SourceHut.
## Rodar
```bash
python3 main.py
README
cat > main.py <<'PY' def main(): print("Olá, SourceHut")
if name == "main": main() PY
cat > .gitignore <<'GITIGNORE' .venv/ pycache/ *.pyc .env GITIGNORE
git add . git commit -m "Initial commit" git branch -M main git remote add origin git@git.sr.ht:~pablo/exemplo-python git push -u origin main
Antes do push, crie o repo:
```bash
hut git create exemplo-python -v private
26. Exemplo completo: Node.js
mkdir exemplo-node
cd exemplo-node
npm init -y
git init
cat > index.js <<'JS'
console.log("Olá, SourceHut");
JS
cat > .gitignore <<'GITIGNORE'
node_modules/
.env
npm-debug.log*
dist/
GITIGNORE
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin git@git.sr.ht:~pablo/exemplo-node
git push -u origin main
Criando antes:
hut git create exemplo-node -v private
27. Usando SourceHut como backup privado
Você pode manter GitHub/Codeberg e SourceHut ao mesmo tempo.
Adicionar SourceHut como segundo remoto:
git remote add srht git@git.sr.ht:~pablo/meu-projeto
Enviar para SourceHut:
git push srht main
Enviar para remoto padrão:
git push origin main
Para backup privado, isso é excelente.
28. HTTPS ou SSH?
Use HTTPS para clonar público rápido:
git clone https://git.sr.ht/~usuario/projeto
Use SSH para seus projetos e para dar push:
git clone git@git.sr.ht:~usuario/projeto
Recomendação: configure SSH e use SSH como padrão.
29. Checklist inicial
[ ] Entrar em meta.sr.ht
[ ] Cadastrar chave SSH pública
[ ] Testar ssh git@git.sr.ht
[ ] Criar repositório em git.sr.ht
[ ] Criar projeto local com git init
[ ] Criar README.md
[ ] Criar .gitignore
[ ] Fazer primeiro commit
[ ] Adicionar remote SSH
[ ] Fazer git push -u origin main
[ ] Clonar em outra pasta para testar
[ ] Instalar/configurar hut depois
Não pule o teste de clone. Se você não consegue clonar seu próprio repo em outra pasta, a configuração não está redonda.
30. Mini mapa mental
SourceHut
│
├── meta.sr.ht
│ ├── conta
│ ├── SSH keys
│ └── tokens OAuth/API
│
├── git.sr.ht
│ ├── repositórios Git
│ ├── clone
│ ├── push
│ └── permissões
│
├── builds.sr.ht
│ └── CI via .build.yml
│
├── todo.sr.ht
│ └── tarefas/issues
│
├── lists.sr.ht
│ └── listas de email e patches
│
├── man.sr.ht
│ └── documentação/wiki
│
└── pages.sr.ht
└── sites estáticos
31. Ordem certa de aprendizado
- Criar repo em
git.sr.ht. - Configurar SSH.
- Fazer
push,pull,clone. - Instalar e usar
hut. - Organizar README,
.gitignore,.env.example. - Usar repo privado/unlisted/public corretamente.
- Aprender
.build.yml. - Publicar site com
pages.sr.ht. - Usar
todo.sr.ht. - Aprender listas e patches por email.
32. Resumo final sem enrolação
# gerar SSH, se não tiver
ssh-keygen -t ed25519 -C "seu-email@example.com"
cat ~/.ssh/id_ed25519.pub
# cadastrar a chave pública em meta.sr.ht
# criar repo privado
hut git create meu-projeto -v private
# subir projeto local
cd meu-projeto
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin git@git.sr.ht:~pablo/meu-projeto
git push -u origin main
# clonar depois
git clone git@git.sr.ht:~pablo/meu-projeto
Se isso funciona, você já venceu 80% do SourceHut.
O resto é cultura: menos botão, mais Git; menos plataforma social, mais ferramenta; menos “pull request”, mais patch; menos maquiagem, mais controle.
33. Fontes consultadas
- SourceHut oficial: https://sourcehut.org/
- Documentação GraphQL oficial do SourceHut: https://docs.sourcehut.org/
- Manual do
hutno Arch Linux: https://man.archlinux.org/man/hut.1.en - Man page agregada do
hut: https://www.mankier.com/1/hut - SourceHut Pages — automating deployments: https://srht.site/automating-deployments/
- Hugo — Host on SourceHut Pages: https://gohugo.io/host-and-deploy/host-on-sourcehut-pages/
Did this resonate?
Related documents
- 001
- 002
- 003
- 004
- 005