Enviando código

Esta seção é direcionada aos Committers e a todos os interessados em saber como um trecho de código é incorporado ao Django pelos desenvolvedores do projeto. Se você é um membro da comunidade que deseja contribuir com o Django enviando o seu código, dê uma olhada em Trabalhando com Git e GitHub.

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.

Evite usar o botão “Merge pull request” no site do GitHub já que isso cria um “merge commit” tosco fazendo a navegação no histórico ficar mais difícil.

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.

    Se você trouxer algo novo para a lista django-developers e ninguém te respondeu por favor não entenda isso como sendo um sinal de que a sua ideia é excelente e deve ser implementada imediatamente já ninguém a contestou. Os desenvolvedores do Django não tem muito tempo disponível para ler as discussões na lista de e-mail imediatamente. Então você pode precisar esperar alguns dias antes de conseguir uma resposta.

  • 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.”

    As mensagens de commit devem ser em linhas de no máximo 72 caracteres. Deve existir uma linha de assunto, separada por uma linha em branco e então parágrafos de linhas de 72 caracteres. Os limites são boas práticas. Para a linha de assunto, quanto mais curta melhor. Em um corpo de uma mensagem de commit mais detalhes é melhor que menos:

    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.”

  • Limite os commits para a mudança mais granular que fizer sentido. Isso significa, fazer uso de commits pequenos e frequentes ao invés de commits grandes e pouco frequentes. Por exemplo, se implementar a funcionalidade X requer uma pequena mudança na biblioteca Y, primeiro faça um commit da mudança na biblioteca Y, depois faça commit da funcionalidade X em um outro commit separado. Isso já facilita muito no processo de ajudar todos os desenvolvedores do Django a seguir as suas alterações.

  • 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.

  • Escreva mensagens de commit para backports usando este formato:

    [<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.

Back to Top