3  Versionamento de código

Em muitas vagas para Cientista de Dados você não vai ver que precisa ter conhecimento de versionamento de código, que vai incluir conhecimentos de Git e de ferramentas como GitHub ou GitLab. Porém, este é um conhecimento básico e essencial para todo mundo que programa em qualquer linguagem de programação e para qualquer fim, seja para Data Science ou para desenvolvimento de software.

3.1 Git

Git é um sistema de controle de versão. Ele rastreia todas as mudanças feitas no seu código ao longo do tempo, permitindo que você:

  • Volte para versões anteriores do código quando necessário
  • Trabalhe em equipe sem sobrescrever o trabalho dos outros
  • Mantenha um histórico completo de todas as alterações feitas

Os códigos de qualquer linguagem de programação são apenas arquivos de texto. Um arquivo em Python ou em R não terão a extensão .txt, mas sim suas próprias extensões: .py e .R, respectivamente. O Git está interessado apenas nesses arquivos de texto, não na execução deles.

Um repositório (ou “repo”) é simplesmente uma pasta no seu computador onde o Git está rastreando as mudanças. Dentro dessa pasta existe uma subpasta oculta chamada .git que contém todo o histórico de versões.

3.2 Instalando o Git

3.2.1 Windows

  1. Baixe o instalador em git-scm.com
  2. Execute o instalador e siga as opções padrão
  3. Após instalar, você terá acesso ao Git Bash, um terminal para usar o Git

3.2.2 Mac

# Opção 1: via Homebrew
brew install git

# Opção 2: Xcode Command Line Tools (instala Git junto)
xcode-select --install

3.2.3 Linux

# Ubuntu/Debian
sudo apt install git

# Fedora/CentOS
sudo yum install git

3.2.4 Configuração inicial

Após instalar, configure seu nome e email. Essas informações aparecem em cada commit que você fizer:

git config --global user.name "Seu Nome"
git config --global user.email "seu@email.com"

3.3 Fluxo de Estados do Git

O Git organiza seus arquivos em três estados:

  1. Working Directory: arquivos modificados, mas ainda não preparados
  2. Staging Area: arquivos preparados para o próximo commit
  3. Repository: histórico de versões salvas (commits)

flowchart LR
    A[Working Directory<br/>Arquivos modificados] -->|git add| B[Staging Area<br/>Prontos para commit]
    B -->|git commit| C[Repository<br/>Histórico salvo]

    style A fill:#ffcccc,stroke:#cc0000
    style B fill:#ffffcc,stroke:#cccc00
    style C fill:#ccffcc,stroke:#00cc00

Você modifica arquivos, usa git add para prepará-los, e git commit para salvar uma versão.

3.4 Comandos do Dia a Dia

Estes são os comandos que você vai usar na maior parte do tempo:

Comando O que faz
git init Cria um novo repositório na pasta atual
git status Mostra o estado atual (arquivos modificados, preparados, etc.)
git add arquivo Prepara um arquivo para commit
git add . Prepara todos os arquivos modificados
git commit -m "mensagem" Salva uma versão com uma mensagem descritiva
git log Mostra o histórico de commits
git diff Mostra as mudanças que ainda não foram preparadas

3.4.1 Exemplo prático

# Criar um repositório
git init

# Ver o estado atual
git status

# Modificar um arquivo e ver as mudanças
git diff

# Preparar arquivos para commit
git add analise.R
git add modelo.py

# Ou preparar todos de uma vez
git add .

# Salvar a versão
git commit -m "adiciona análise exploratória e primeiro modelo"

# Ver o histórico
git log

3.5 Branches

Branches são linhas de desenvolvimento paralelas. Elas permitem que você trabalhe em uma nova funcionalidade sem afetar o código principal.

gitGraph
    commit id: "inicial"
    commit id: "v1"
    branch feat/novo-grafico
    commit id: "adiciona dados"
    commit id: "cria gráfico"
    checkout main
    commit id: "fix typo"
    merge feat/novo-grafico id: "merge"
    commit id: "v2"

Por padrão, todo repositório começa com uma branch chamada main (ou master em repos mais antigos).

3.5.1 Comandos de branches

# Listar branches
git branch

# Criar uma nova branch
git branch nome-da-branch

# Mudar para outra branch
git checkout nome-da-branch
# ou
git switch nome-da-branch

# Criar e mudar para uma nova branch (atalho)
git checkout -b nome-da-branch

# Juntar uma branch na atual
git merge nome-da-branch

3.5.2 Exemplo prático

# Estou na main, quero criar uma feature
git checkout -b feat/novo-grafico

# Faço minhas alterações...
git add .
git commit -m "adiciona gráfico de dispersão"

# Volto para main e junto as alterações
git checkout main
git merge feat/novo-grafico

3.6 Git Workflow com Feature Branches

3.6.1 Fluxo básico (times pequenos)

Para projetos pessoais ou times pequenos, o fluxo é simples:

  1. Branch principal (main) sempre estável
  2. Criar branch para cada feature: feat/nome-da-feature
  3. Commits pequenos e frequentes
  4. Push para remoto
  5. Pull Request / Merge Request
  6. Code review
  7. Merge para main

3.6.2 Fluxo com múltiplos ambientes

Quando há ambientes separados (desenvolvimento, homologação, produção), o fluxo fica mais estruturado:

Branches de ambiente:

  • main ou prod → código em produção (o que está rodando de verdade)
  • stg ou uat → ambiente de homologação (testes finais antes de ir pra prod)
  • dev ou develop → ambiente de desenvolvimento (integração das features)

gitGraph
    commit id: "prod v1"
    branch stg
    commit id: "stg sync"
    branch dev
    commit id: "dev sync"
    branch feat/novo-modelo
    commit id: "modelo v1"
    commit id: "ajustes"
    checkout dev
    merge feat/novo-modelo id: "merge dev"
    checkout stg
    merge dev id: "merge stg"
    checkout main
    merge stg id: "deploy prod"
    commit id: "prod v2"

  1. Desenvolvedor cria branch a partir de dev
  2. Faz as mudanças e abre PR para dev
  3. Após code review, merge para dev
  4. Quando dev está pronto para testes, merge para stg
  5. QA testa em staging
  6. Após aprovação, merge de stg para main (deploy em produção)

Exemplo prático:

# Criar feature a partir de dev
git checkout dev
git pull origin dev
git checkout -b feat/novo-modelo

# Trabalhar...
git add .
git commit -m "adiciona modelo de classificação"
git push -u origin feat/novo-modelo

# Abrir PR de feat/novo-modelo → dev
# Após aprovação e merge, o CI/CD faz deploy em ambiente dev

# Quando pronto para staging
git checkout stg
git pull origin stg
git merge dev
git push origin stg
# CI/CD faz deploy em staging para QA testar

# Quando aprovado, vai para produção
git checkout main
git pull origin main
git merge stg
git push origin main
# CI/CD faz deploy em produção

Quando usar cada modelo:

Cenário Modelo sugerido
Projeto pessoal / time de 1-2 pessoas main + feature branches
Time pequeno (3-5 pessoas) main + dev + feature branches
Time maior / produto em produção main + stg + dev + feature branches

3.6.3 Convenções de nomes de branches

  • feat/ - nova funcionalidade
  • fix/ - correção de bug
  • docs/ - documentação
  • refactor/ - refatoração
  • hotfix/ - correção urgente direto para produção

3.7 Resolução de Conflitos

Conflitos acontecem quando duas pessoas editam o mesmo trecho de código. O Git não sabe qual versão manter e pede para você decidir.

3.7.1 Exemplo passo a passo

  1. Você tenta fazer merge e vê a mensagem de conflito:
git merge feat/outra-feature
# Auto-merging analise.R
# CONFLICT (content): Merge conflict in analise.R
  1. Abre o arquivo com conflito e vê as marcações:
# analise.R
library(dplyr)

<<<<<<< HEAD
dados <- read.csv("dados_v2.csv")
=======
dados <- read.csv("dados_limpos.csv")
>>>>>>> feat/outra-feature

resultado <- dados |>
  filter(valor > 0)
  1. O que significam as marcações:
    • Entre <<<<<<< HEAD e =======: seu código (branch atual)
    • Entre ======= e >>>>>>>: código da outra branch
  2. Decide o que manter. Pode ser um, outro, ou uma combinação:
# analise.R
library(dplyr)

dados <- read.csv("dados_limpos.csv")  # escolhi a versão da outra branch

resultado <- dados |>
  filter(valor > 0)
  1. Remove as marcações, salva o arquivo e finaliza:
git add analise.R
git commit -m "resolve conflito em analise.R"

3.7.2 Boas práticas para evitar conflitos

  • Faça commits frequentes
  • git pull antes de começar a trabalhar
  • Mantenha branches de curta duração

3.8 Comandos de Emergência

Quando algo dá errado, estes comandos podem salvar:

Situação Comando
Ver o que mudou git diff
Descartar mudanças não commitadas em um arquivo git checkout -- arquivo
Guardar mudanças temporariamente git stash
Recuperar mudanças guardadas git stash pop
Desfazer último commit (mantendo mudanças) git reset --soft HEAD~1
Desfazer último commit (descartando TUDO) git reset --hard HEAD
Desfazer commit mantendo histórico git revert HEAD

3.9 .gitignore para Data Science

O arquivo .gitignore diz ao Git quais arquivos não devem ser versionados. Para projetos de Data Science, não versionamos:

  • Dados grandes (.csv, .parquet, .rds, .pkl)
  • Credenciais (.env, .Renviron)
  • Ambientes virtuais (venv/, renv/library/)
  • Cache e arquivos temporários

3.9.1 Exemplo para projetos em R

# Dados
*.csv
*.parquet
*.rds
*.RData
data/raw/

# Ambiente e configurações locais
.Renviron
.Rprofile
.Rhistory
.RData

# renv (pacotes instalados)
renv/library/
renv/staging/

# Arquivos de sessão
.Rproj.user/

# Outputs de Quarto/RMarkdown
*_cache/
*_files/

3.9.2 Exemplo para projetos em Python

# Dados
*.csv
*.parquet
*.pkl
*.h5
data/raw/

# Ambiente
.env
venv/
.venv/

# Cache
__pycache__/
*.pyc
.cache/

# Jupyter
.ipynb_checkpoints/

3.9.3 Exemplo combinado (R + Python)

# Dados (ambos)
*.csv
*.parquet
data/raw/

# R
*.rds
*.RData
.Renviron
.Rhistory
renv/library/
.Rproj.user/

# Python
*.pkl
.env
venv/
__pycache__/
.ipynb_checkpoints/

3.10 GitHub e GitLab

Git é o sistema de versionamento que roda localmente no seu computador. GitHub e GitLab são serviços na nuvem que hospedam repositórios Git, permitindo colaboração e backup.

3.10.1 Conectar repositório local ao remoto

# Adicionar um repositório remoto
git remote add origin https://github.com/usuario/repo.git

# Enviar código para o remoto pela primeira vez
git push -u origin main

3.10.2 Comandos para trabalhar com remoto

# Enviar commits para o remoto
git push

# Trazer atualizações do remoto
git pull

# Baixar um repositório existente
git clone https://github.com/usuario/repo.git

3.10.3 Pull Requests / Merge Requests

Pull Request (GitHub) ou Merge Request (GitLab) é a forma de propor mudanças de uma branch para outra. O fluxo típico é:

  1. Você cria uma branch e faz commits
  2. Push da branch para o remoto
  3. Abre um PR/MR no site (GitHub ou GitLab)
  4. Colegas revisam o código
  5. Após aprovação, faz o merge

Isso permite code review antes de integrar mudanças, o que melhora a qualidade do código e distribui conhecimento no time.

3.11 Boas Práticas para Cientistas de Dados

  • Commits frequentes com mensagens descritivas: prefira “adiciona modelo de regressão logística” em vez de “update”
  • Não versione dados brutos grandes: use links ou armazene em cloud storage (S3, GCS, Azure Blob)
  • Cuidado com notebooks: arquivos .ipynb geram diffs confusos. Considere limpar outputs antes de commitar ou use ferramentas como nbstripout
  • Use branches para experimentos: quando for testar uma abordagem diferente, crie uma branch. Se não funcionar, é só descartar
  • README com instruções de setup: documente como configurar o ambiente, instalar dependências e rodar o projeto