Backup de repositórios Git: estratégias e ferramentas

1. Por que fazer backup de repositórios Git?

Muitos desenvolvedores acreditam que, por usarem plataformas como GitHub, GitLab ou Bitbucket, seus repositórios estão automaticamente seguros. Essa suposição é perigosa. Embora essas plataformas ofereçam alta disponibilidade, elas não garantem proteção contra todos os cenários de perda de dados: remoção acidental de branches por um colaborador, corrupção de objetos no repositório remoto, falhas catastróficas no servidor da plataforma ou até mesmo o bloqueio de uma conta.

É crucial entender a diferença entre backup e mirroring. Um backup é uma cópia pontual e armazenada separadamente, criada para restauração em caso de desastre. Mirroring, por outro lado, é uma sincronização contínua que mantém duas cópias idênticas em tempo real. Embora mirroring ofereça redundância, ele não protege contra corrupção propagada ou exclusão acidental — se um branch for deletado no espelho, ele será deletado na réplica. Para proteção real, você precisa de backups históricos e versionados.

2. Estratégias fundamentais de backup

A estratégia mais simples e completa é o git clone --mirror. Esse comando cria uma réplica exata do repositório, incluindo todas as referências (branches, tags) e objetos. Diferente de um clone comum, o mirror é um repositório bare, ou seja, sem diretório de trabalho, e contém absolutamente tudo que o repositório original possui.

git clone --mirirror https://github.com/usuario/repo.git repo-backup.git

Para manter o backup atualizado sem recriá-lo do zero, utilize git fetch --prune em um repositório bare preexistente. O --prune remove referências que foram deletadas no remoto, mantendo o backup sincronizado.

cd repo-backup.git
git fetch --prune origin

Além dos objetos Git, considere fazer backup de metadados adicionais: hooks personalizados, configurações do servidor (como arquivos gitolite.conf ou authorized_keys) e permissões de acesso. Esses itens geralmente não são versionados e podem ser essenciais para uma recuperação completa.

3. Ferramentas nativas do Git para backup

O git bundle é uma ferramenta poderosa para criar arquivos portáteis de backup. Um bundle é um único arquivo que contém todos os objetos e referências de um repositório, ideal para transporte físico ou envio para armazenamento externo.

git bundle create repo-backup.bundle --all

Para restaurar a partir de um bundle:

git clone repo-backup.bundle repo-restaurado

Antes de realizar um backup, otimize o repositório para reduzir o tamanho dos dados transferidos. Use git repack para consolidar objetos em menos pacotes e git gc para remover objetos inalcançáveis.

git -C repo-backup.git repack -a -d --depth=250 --window=250
git -C repo-backup.git gc --aggressive --prune=now

Para ambientes com servidores Linux, rsync é uma ferramenta eficiente para sincronizar repositórios bare entre servidores locais. Ele transfere apenas as diferenças, economizando largura de banda.

rsync -avz --delete repo-backup.git/ usuario@servidor-local:/caminho/backup/repo-backup.git/

4. Automação e agendamento de backups

Para garantir backups regulares, configure um cron job que execute git fetch --mirror periodicamente. Exemplo de entrada no crontab para backup diário às 2h da manhã:

0 2 * * * /usr/bin/git -C /caminho/repo-backup.git fetch --prune origin

Em servidores Git, você pode usar um hook post-receive para disparar um backup automático sempre que um push for recebido. O script abaixo é executado no servidor após cada push e sincroniza o repositório para um backup remoto.

#!/bin/bash
# Hook post-receive: backup automático para servidor remoto
TARGET="usuario@servidor-backup:/backups/repositorios/"
rsync -avz --delete /caminho/repo-bare.git/ "$TARGET"

Para backup diário com compressão e rotação, um script Bash mais completo pode ser utilizado:

#!/bin/bash
# Script de backup diário com compressão e rotação
REPO_URL="https://github.com/usuario/repo.git"
BACKUP_DIR="/backups/repos"
DATE=$(date +%Y-%m-%d)

# Clona mirror
git clone --mirror "$REPO_URL" "$BACKUP_DIR/repo-$DATE.git"

# Compacta
tar -czf "$BACKUP_DIR/repo-$DATE.tar.gz" -C "$BACKUP_DIR" "repo-$DATE.git"

# Remove repositório descompactado
rm -rf "$BACKUP_DIR/repo-$DATE.git"

# Rotação: mantém apenas os últimos 30 backups
ls -t "$BACKUP_DIR"/*.tar.gz | tail -n +31 | xargs -I {} rm -- {}

5. Backup remoto e offsite

Aplique a estratégia 3-2-1 aos seus repositórios Git: mantenha três cópias dos dados, em dois tipos de mídia diferentes, com uma cópia offsite. Por exemplo: a cópia primária no GitHub, uma cópia local em um servidor NAS e uma cópia em um provedor de cloud (AWS S3, Backblaze B2).

Para criar uma cópia remota, faça push do seu repositório bare para um servidor alternativo:

git remote add backup ssh://usuario@vps-backup.com:/backups/repo.git
git push --mirror backup

Para transporte físico ou envio para serviços de armazenamento como S3, utilize git bundle. O bundle pode ser enviado via scp ou com ferramentas como aws s3 cp:

git bundle create repo-backup.bundle --all
scp repo-backup.bundle usuario@vps-backup.com:/backups/
aws s3 cp repo-backup.bundle s3://meu-bucket-git-backups/

6. Restauração e validação do backup

Um backup só é útil se puder ser restaurado. Valide regularmente a integridade do seu repositório de backup com git fsck:

git -C repo-backup.git fsck --full

Esse comando verifica a consistência de todos os objetos e referências. Se nenhum erro for reportado, o backup está íntegro.

Para restaurar a partir de um backup bare, simplesmente faça um clone:

git clone repo-backup.git repo-restaurado

Se o backup estiver em formato bundle:

git clone repo-backup.bundle repo-restaurado

Agende testes periódicos de restauração. Crie um script que clone o backup em um diretório temporário, execute git log e git fsck, e depois remova o diretório. Isso garante que o backup é funcional.

7. Ferramentas externas e práticas corporativas

Para ambientes corporativos, considere ferramentas especializadas como bup (git-based backup system), que utiliza a estrutura de objetos do Git para backups incrementais e deduplicados. O gitolite oferece gerenciamento de permissões e pode ser integrado a scripts de backup. O Gitea ou GitLab self-hosted possuem funcionalidades de backup integradas que exportam todo o banco de dados e repositórios.

Integre os backups Git com soluções corporativas tradicionais. Ferramentas como Bacula, Veeam ou AWS Backup podem fazer snapshots do sistema de arquivos onde os repositórios bare estão armazenados. Para ambientes AWS, o AWS Backup pode gerenciar snapshots de volumes EBS que contêm repositórios.

Defina políticas de retenção claras. Por exemplo, mantenha snapshots diários por 7 dias, semanais por 4 semanas e mensais por 12 meses. Para bundles históricos, considere reter versões antigas por pelo menos um ano para atender requisitos de compliance.

8. Considerações finais e boas práticas

Documente seu plano de backup: especifique quais repositórios são cobertos, a frequência dos backups, o método utilizado, o responsável pela execução e o procedimento de restauração. Mantenha essa documentação acessível a toda a equipe.

Realize testes de recuperação trimestralmente. Simule um desastre (exclusão de um repositório no servidor principal) e execute o procedimento de restauração completo. Cronometre o processo e documente quaisquer problemas encontrados.

Diferencie as necessidades de backup entre repositórios pessoais e corporativos. Projetos pessoais podem ser protegidos com um simples script de mirroring diário. Já ambientes corporativos exigem políticas de retenção, testes regulares, trilhas de auditoria e conformidade com regulamentações como SOC 2 ou ISO 27001.

Lembre-se: confiar cegamente em plataformas terceiras não é uma estratégia de backup. Tenha o controle dos seus dados. Implemente uma estratégia de backup robusta hoje, antes que um desastre aconteça.

Referências