git
amend e rebase existem.
Pull Requests não.
2019 - Cléber Zavadniak
https://medium.com/@cleber.z
Pull Requests
Pull Request
- Excelente ferramenta de code review.
- Serve como uma unidade conceitual.
- Todavia, é etéreo.
Etéreo
Volátil
Temporário
Etéreo
Volátil
Temporário
Sintomas
Commits devem entregar valor!
- "create structure to new service"
- Valor entregue: nenhum.
Péssimo
- Novo comando no Makefile
- Criação de nova app
- Modelagem do banco
- Migrações
- Endpoint: GET
- Endpoint: POST
- Testes
- Envio de e-mail de notificação
Ideal
- Suporte a "esqueci minha senha"
- Fix: bug#42
- Endpoint de notificações
- Migração para Django 2.2.5
Exercício mental
- Cada commit é enviado e analisado individualmente.
- Quem analisa não faz ideia de qual é o objetivo final.
Pull Request:
"Você poderia, por favor, mexer nisso e nisso no teu código?"
Reação normal:
- Pra que diabos uma tabela de tokens OAuth2 se não temos integração com OAuth2?
- Não entra código sem propósito na base.
- "Vamos precisar disso no futuro" não é um argumento válido!
Commit: "Nova tabela: oauth2_tokens"
Valor!
- Suporte a "esqueci minha senha"
- Feature
- Fix: bug#42
- Bugfix
- Endpoint de notificações
- Feature
- Migração para Django 2.2.5
- Mudança significativa na base de código
Commits, não PRs
- Ninguém mais vê um "PR" depois que ele é aceito.
- Cada commit é uma entrega completa.
- A alteração deve ser relevante.
- Isso te obriga a planejar direito as tarefas.
"Planejar direito as tarefas?"
Processo
- Tarefas não podem ser muito grandes.
- Atômicas, mas no sentido de entrega de valor.
- Desenvolvedor começa a trabalhar sabendo exatamente o que deseja entregar no final.
- (Algumas equipes costumam fazer associação 1:1 entre commits e User Stories, inclusive.)
DESIGN
- Curiosamente, isso afeta os designers, também.
- As "telas" devem aceitar implementação incremental.
Mas como fazer isso?
Fluxo normal
- Abre um galho com nome descritivo
- Faz a parte 1
- Commit
- Faz a parte 2
- Commit
- Faz a parte 3
- Commit
- Push
- Pull Request
Esse fluxo "normal" é terrível!
Fluxo terrível
- Pedidos de alteração no PR
- Altera
- Commit && push
- Pedidos de alteração no PR
- Altera
- Commit && push
- Pedidos de alteração no PR
- Altera
- Commit && push
- Pedidos de alteração no PR
- Altera
- Commit && push
Resultado
- Parte 1
- Parte 2
- Parte 3
- Fix
- Fix
- Improvements
- Fix
- Bugfix
- Fix
- Improvements
- Fix
- Fix
- Bugfix
amend ao resgate!
amend
- Faz a parte 1
-
git add . # Contanto que você tenha um bom .gitignore!
- git commit -m 'Suporte a "esqueci minha senha"'
- Faz a parte 2
-
git add . && git commit -amend -C HEAD
- Faz a parte 3
-
git add . && git commit -amend -C HEAD
-
git push
- Pull Request
Resultado
- Entrega feita em 1 commit.
- Code review ajuda a melhorar o commit.
- E não "melhorar o Pull Request".
- Porque o PR não existe.
- E não "melhorar o Pull Request".
- Code review longo não prejudica a legibilidade do histórico.
Em paralelo
Numa equipe
- Várias pessoas trabalhando na mesma base de código.
- Galho de origem muda enquanto você trabalha numa tarefa.
Método comum
- Novo galho a partir do galho-mestre
- Brás Cubas: Trabalha na feature 1
- Quincas Borba: Trabalha na feature 2
- Brás Cubas: merge na master
- Quincas Borba: merge na master
Problemas
- Merges geralmente grandes e complicados.
- Você provavelmente estará trabalhando numa base de código desatualizada por um bom tempo...
- Coisas imprevisíveis podem acontecer.
Exemplo
- Novo galho a partir do galho-mestre.
- Brás Cubas: implementando "esqueci minha senha".
- Quincas Borba: upgrade para Django 2.2.5 .
- Quincas Borba: merge no galho-mestre.
-
Brás Cubas: prosseguindo no seu trabalho.
- Ainda na versão anterior do framework.
- Muita coisa já deveria estar sendo feita de forma diferente.
- Só ficará sabendo quando terminar sua tarefa.
- Potencialmente fará muita coisa pensando em Django < 2.2.5 .
Solução: serialização
Serialização
- Só se começa a trabalhar a partir da versão mais atual.
- Uma alteração por vez, sem exceções.
- Só se faz merge para o galho-mestre.
Exemplo
- branch do Quincas Borba → Epsilo
- Delta → branch do Quincas Borba
- branch do Brás Cubas → Delta
- Gama → branch do Brás Cubas
- Beta
- Alfa
(Leia de baixo para cima)
Certo?
Mas... mas...
As pessoas trabalham paralelamente!
git rebase master
- Começo do teu commit ← versão mais atual do galho-mestre
- Eu vou garantindo que "sou o próximo" conforme os outros vão integrando suas mudanças.
Fluxo
-
git checkout master # Atualiza o
-
git pull # galho-mestre local
-
git checkout esqueci-minha-senha
-
git rebase master
-
Se houver diferenças, resolvê-las agora.
"Simple Git Workflow For Continuous Delivery"
by leesmith
https://gist.github.com/leesmith/8441773
Processo
- Atualizar o galho-mestre local todo dia.
- Se houve alterações, rebase nos feature branches.
Resultado
- Todo commit:
- É uma entrega completa.
- É uma alteração baseada no último commit do galho-mestre.
- Todo merge é para dentro do galho-mestre.
- Histórico claro.
- Merges (durante os rebases) geralmente mais simples.
- A maioria acaba sendo fast-forwarded, de qualquer forma...
Ademais...
- Mesmo sem fazer rebase, você faz "rebases".
- Você criou o feature branch no mês passado.
- Muita coisa mudou no galho-mestre.
- Ao fazer o merge:
- Você será confrontado com toda alteração que não seria fast-forwarded durante os rebases.
Ou seja
- É o mesmo trabalho.
- Só que mais implícito.
- E "explícito é melhor do que implícito".
- E mais volumoso.
- A complexidade tende a aumentar de maneira exponencial, não linear.
Fim
- Pull Requests não existem
- Commits devem entregar valor completo individualmente
- git commit -amend -C HEAD
- git rebase master
https://medium.com/@cleber.z
git
By Cléber Zavadniak
git
- 297