Enviando código¶
This section is addressed to the committers and to anyone interested in knowing how code gets committed into Django. If you’re a community member who wants to contribute code to Django, look at Trabalhando com Git e GitHub instead.
Manipulando pull requests¶
Como o Django agora é hospedado no GitHub, a maioria das melhorias é fornecida na forma de pull requests.
Ao fazer um pull request, certifique-se de que cada commit individualmente satisfaça as regras descritas abaixo. Espera-se de quem contribui os melhores pull requests possíveis de se fornecer. Na prática, entretanto, os committers, - quem provavelmente estará mais familiarizado com as regras do projeto - podem decidir melhorar a qualidade de um commit por conta própria.
Nota
Antes de fazer um merge, mas depois de revisar, faça com que o Jenkins teste o pull request comentando “buildbot, test this please” no PR. Veja nossa página wiki do ‘Jenkins’_ para mais detalhes.
Um jeito fácil de fazer checkout de um pull request localmente é adicionando um alias no seu ~/.gitconfig
(estamos assumindo que django/django
é o nosso upstream
):
[alias]
pr = !sh -c \"git fetch upstream pull/${1}/head:pr/${1} && git checkout pr/${1}\"
Agora você pode simplesmente executar git pr ####
para realizar o checkout do pull request correspondente.
A partir deste momento, você pode trabalhar no código. Utilize git rebase -i
e git commit --amend
para garantir que os commits tenham o nível de qualidade desejado. Quando você estiver pronto:
$ # Pull in the latest changes from master.
$ git checkout master
$ git pull upstream master
$ # Rebase the pull request on master.
$ git checkout pr/####
$ git rebase master
$ git checkout master
$ # Merge the work as "fast-forward" to master to avoid a merge commit.
$ # (in practice, you can omit "--ff-only" since you just rebased)
$ git merge --ff-only pr/XXXX
$ # If you're not sure if you did things correctly, check that only the
$ # changes you expect will be pushed to upstream.
$ git push --dry-run upstream master
$ # Push!
$ git push upstream master
$ # Delete the pull request branch.
$ git branch -d pr/xxxx
Para mudanças em suas próprias branches, force o push no seu fork depois de fazer o rebase na master mas antes de fazer merge e push para o upstream. Isso permite que os hashes dos commits na master e na sua branch coincidam o que fecha o pull request automaticamente. Como você não pode fazer push na branch de outros contribuidores, comente no pull request “Merged in XXXXXXX” (trocando pelo hash do commit) depois que você fizer o merge. Trac procura esse formato de mensagem para indicar na página do ticket se foi feito um merge de um pull request ou não.
If a pull request doesn’t need to be merged as multiple commits, you can use GitHub’s “Squash and merge” button on the website. Edit the commit message as needed to conform to the guidelines and remove the pull request number that’s automatically appended to the message’s first line.
Quando estiver reescrevendo o histórico de commits de um pull request, o objetivo é fazer com que o histórico de commits do Django seja o mais útil possível:
- Se um patch possui retornos e avanços nos commits, então reescreva esses em um só. Por exemplo, se um commit adiciona mais código e um segundo commit faz ajustes em problemas de estilo introduzidos pelo primeiro commit, esses commits devem ser unificados antes de se fazer um merge.
- Separe as mudanças em diferentes commits por grupos lógicos: se você faz uma limpeza de estilo ao mesmo tempo em que você faz outras mudanças em um arquivo, a separação dessas mudanças em dois commits diferentes fará a revisão do histórico de alterações mais simples.
- Cuidado com merges de branches do upstream dentro de pull requests.
- Testes devem passar e a documentação deve ser gerada depois de cada commit. Nem os testes, nem a documentação devem emitir avisos.
- Patchs triviais e pequenos costumam ser melhor realizados em um único commit. Já trabalhos médios ou maiores podem ser quebrados em múltiplos commits se isso fizer sentido.
Praticidade vence pureza, então vai de cada committer decidir o quanto refinar o histórico antes de um pull request. Os principais objetivos devem ser engajar a comunidade, terminar o trabalho, e ter um histórico de commits utilizável.
Regras de commit¶
Adicionalmente, por favor siga as regras a seguir quando estiver commitando código para o repositório do Django no git:
Nunca altere o histórico publicado dos “branches” do
django/django
através de um “push” forçado. Se for absolutamente necessário (por razões de segurança), primeiro discuta a situação com o time.Para qualquer mudança de média para grande, onde “média para grande” é de acordo com o seu próprio julgamento, por favor traga o problema para a lista de e-mail django-developers antes de fazer a mudança.
If you bring something up on django-developers and nobody responds, please don’t take that to mean your idea is great and should be implemented immediately because nobody contested it. Everyone doesn’t always have a lot of time to read mailing list discussions immediately, so you may have to wait a couple of days before getting a response.
Escreva os commits com mensagens detalhadas e utilizando o passado como tempo verbal, não o presente.
- Bom: “Corrigido bug de Unicode na API de RSS.”
- Ruim: “Corrige bug de Unicode na API de RSS.”
- Ruim: “Corrigindo bug de Unicode na API de RSS.”
The commit message should be in lines of 72 chars maximum. There should be a subject line, separated by a blank line and then paragraphs of 72 char lines. The limits are soft. For the subject line, shorter is better. In the body of the commit message more detail is better than less:
Fixed #18307 -- Added git workflow guidelines Refactored the Django's documentation to remove mentions of SVN specific tasks. Added guidelines of how to use Git, GitHub, and how to use pull request together with Trac instead.
Se o patch não foi um pull request, você deverá dar crédito as pessoas que contribuiram na mensagem de commit: “Obrigado A por avisar, B pelo patch e C por revisar.”
Para commits em uma branch, coloque antes da mensagem de commit o nome da branch. Por exemplo: “[1.4.x] Corrigido #xxxxx – Adicionado suporte para leitura de mentes.”
Limit commits to the most granular change that makes sense. This means, use frequent small commits rather than infrequent large commits. For example, if implementing feature X requires a small change to library Y, first commit the change to library Y, then commit feature X in a separate commit. This goes a long way in helping everyone follow your changes.
Separe as correções de bug das mudanças nas funcionalidades. Correções de bug podem ter que ser portadas para a branch stable, de acordo com a backwards-compatibility política de compatibilidade.
Se o seu commit fecha um ticket no rastreador de tickets do Django, comece a sua mensagem de commit com o texto “Fixed #xxxxx”, onde “xxxxx” é o número do ticket que o seu commit corrige. Exemplo: “Corrigido #123 – Adicionada a funcionalidade whizbang.”. Nós configuramos o Trac de modo que qualquer mensagem de commit nesse formato irá automaticamente fechar o ticket referenciado e colocar um comentário nele com a mensagem completa do commit.
Se o seu commit fecha um ticket e está dentro de uma branch, utilize o nome da branch primeiro, depois o “Corrigido #xxxxx.” Por exemplo: “[1.4.x] Corrigido #123 – Adicionada a funcionalidade whizbang.”
Para os curiosos, nós estamos utilizando um plugin do Track para isso.
Nota
Repare que a integração com o Trac não sabe nada sobre os pull requests. Portanto, se você tentar fechar um pull request com a frase “encerra #400 na sua mensagem de commit, o GitHub irá fechar o pull request, mas o plugin do Trac irá fechar também o respectivo ticket dentro do Trac.
Se o seu commit faz referência a um ticket no rastreador de tickets do Django mas não fecha o ticket, inclua a frase “Refs #xxxxx”, onde “xxxxx” é o número do ticket que o seu commit faz menção. Isso irá automaticamente postar um comentário na página do respectivo ticket.
Write commit messages for backports using this pattern:
[<Django version>] Fixed <ticket> -- <description> Backport of <revision> from <branch>.
Por exemplo:
[1.3.x] Fixed #17028 -- Changed diveintopython.org -> diveintopython.net. Backport of 80c0cbf1c97047daed2c5b41b296bbc56fe1d7e3 from master.
Existe um script na wiki para automatizar isso.
Revertendo commits¶
Ninguém é perfeito; erros serão comitados.
Mas esforce-se de verdade para garantir que erros não aconteçam. O fato de termos uma política de reversão não reduz a sua responsabilidade em buscar o maior padrão de qualidade possível. De verdade: revise o seu trabalho duas vezes, ou deixe ele ser revisado por outro committer, antes de você já ter feito o commit dele!
Quando um commit indevido é descoberto, por favor siga as instruções abaixo:
- Se possível, deixe que o autor original reverta o seu próprio commit.
- Não faça o revert das mudanças de outro autor sem a permissão do autor original.
- Utilize o git revert – isso irá fazer um commit reverso, mas o commit original ainda será parte do histórico de commits.
- Se o autor original não puder ser encontrado (dentro de um prazo razoável – um dia ou algo assim) e o problema é severo – bug quebrando a build, vários testes falhando, etc. – então pergunte se existe alguma objeção na lista de e-mail django-developers e então reverta o código se elas não existirem.
- Se o problema é pequeno (uma funcionalidade congelada, por exemplo) aguarde.
- Se existir um desacordo entre o committer e o autor do código a sofrer um revert então tente solucionar o problema na lista de e-mail django-developers. Se um acordo não puder ser encontrado então o problema deve ser submetido a uma votação.
- Se o commit introduziu uma vulnerabilidade de segurança confirmada, aberta então o commit deve ser revertido imediatamente sem permissão de ninguém.
- O mantenedor da branch de releases pode voltar commits nessa branch sem permissão caso o commit tenha quebrado a branch de releases.
- Se você erroneamente fizer um “push” em um “branch” para “django/django”, apenas delete. Por exemplo, se você fizer
git push upstream feature_antigravity
, apenas reverta o “push”:git push upstream :feature_antigravity
.