Boas maneiras de gerenciar um changelog usando git?

214

Estou usando o Git há algum tempo e recentemente comecei a usá-lo para marcar meus lançamentos, para que eu pudesse acompanhar as alterações com mais facilidade e poder ver qual versão cada um de nossos clientes está executando (infelizmente, o código atualmente exige que cada cliente tenha sua própria cópia do site PHP; estou mudando isso, mas é lento).

De qualquer forma, estamos começando a ganhar impulso, achei que seria muito bom poder mostrar às pessoas o que mudou desde o último lançamento. O problema é que não tenho mantido um registro de alterações porque não tenho uma boa idéia de como fazê-lo. Nesse período em particular, posso executar o log e criar manualmente um, mas isso ficará cansativo muito rapidamente.

Tentei pesquisar no "git changelog" e "git manage changelog", mas não encontrei nada que realmente falasse sobre o fluxo de trabalho das alterações de código e como isso coincide com o changelog. No momento, estamos acompanhando o fluxo de trabalho de desenvolvimento de Rein Henrichs e eu adoraria algo que acompanhasse isso.

Há uma abordagem padrão que me falta, ou essa é uma área em que todos fazem suas próprias coisas?

Muito obrigado por seus comentários / respostas!

Topher Fangio
fonte

Respostas:

181

Isso foi há cerca de 3-4 anos atrás, mas para o futuro dos pesquisadores, agora é possível gerar logs lindos com:

git log --oneline --decorate

Ou, se você quiser ainda mais bonita (com cores para o terminal):

git log --oneline --decorate --color

Canalizar essa saída para o ChangeLog é o que atualmente uso em todos os meus projetos, é simplesmente incrível.


fonte
4
Outra tag útil é --graph, que mostra visualmente em quais ramificações as confirmações estão.
Eruant
44
Eu desaconselharia fortemente o uso de diffs de registro de presentes como um CHANGELOG
Olivier Lacan
4
copiar a git logsaída para o changelog não faz sentido. Você precisa fazer um trabalho de filtragem e edição para ter um registro de alterações legível; caso contrário, por que você precisaria de um registro de alterações? Eu acho que você pode automatizar a geração de um changelog, mas por favor não faça uma cópia bruta do git log!
vaab
19
O problema é que, mesmo assumindo que todos os colaboradores do seu projeto gravem mensagens de confirmação claras e legíveis, você ainda estará gerando um "registro de alterações" contendo toneladas de ruído. Os registros de alterações devem ser escritos com o objetivo de explicar aos usuários do seu projeto as notáveis alterações relevantes a eles que ocorreram entre os lançamentos, enquanto as mensagens de confirmação devem se concentrar em explicar aos desenvolvedores quais melhorias o seu commit faz no código . Às vezes há sobreposição lá, mas nem sempre.
precisa saber é o seguinte
7
Ou, para tornar isso um pouco mais concreto, esse método criará um "log de alterações" contendo muitas entradas como "Ortografia fixa do fooMethod no ZModule" e "Refatorar o XModule para usar a nova versão do XYLibarary". Seus usuários não se importam com isso. Eles querem saber quais alterações foram feitas na perspectiva deles como usuários, não na sua perspectiva como desenvolvedor. E isso até ignora coisas como "Mesclar PR # 123 do xdev / foo" e "Opps, corrigiu newFeature para que realmente funcione" coisas do tipo que provavelmente existirão em qualquer repo do mundo real.
precisa saber é o seguinte
60

Você pode usar algum sabor do git log para ajudá-lo:

git log --pretty=%s                 # only print the subject

Se você nomear suas ramificações de maneira adequada, para que uma mesclagem a ser exibida seja exibida como "Função de ramificação mesclada-foobar", você poderá reduzir as coisas mostrando apenas essa mensagem, e nem todos os pequenos commits que você mesclou, que juntos formam a característica:

git log --pretty=%s --first-parent  # only follow first parent of merges

Você pode aumentar isso com um script próprio, o que pode fazer coisas como remover os bits de "Filial mesclado", normalizar a formatação, etc. Em algum momento, é necessário escrevê-lo, é claro.

Em seguida, você pode criar uma nova seção para o log de alterações uma vez por versão:

git log [opts] vX.X.X..vX.X.Y | helper-script > changelogs/X.X.Y

e confirme isso na versão release.

Se o seu problema é que esses assuntos de submissão não são nada parecidos com o que você gostaria de colocar em um registro de alterações, você tem duas opções: continue fazendo tudo manualmente (e tente acompanhá-lo com mais regularidade em vez de brincar no momento da liberação) ou corrija seu estilo de mensagem de confirmação. Uma opção, se os sujeitos não o fizerem, seria colocar linhas como "change: added feature foobar" nos corpos das mensagens de confirmação, para que mais tarde você pudesse fazer algo como git log --pretty=%B | grep ^change:pegar apenas aquelas bits importantes das mensagens.

Não sei ao certo quanto mais do que esse git poderia realmente ajudá-lo a criar seus changelogs. Talvez eu tenha interpretado mal o que você quer dizer com "gerenciar"?

Cascabel
fonte
2
Definitivamente, esse é um ótimo começo, e eu não tinha pensado em adicionar um modificador ao corpo para poder cumpri-lo mais tarde. Isso pode ser o que acabo fazendo. Obrigado pelo feedback! Se não houver mais respostas vêm no interior no dia seguinte ou assim, eu vou marcar seu como a resposta :-)
Topher Fangio
60

AVISO LEGAL: Eu sou o autor do gitchangelog do qual falarei a seguir.

TL; DR: convém verificar o próprio changelog do gitchangelog ou a saída ascii que gerou a anterior.

Se você deseja gerar um log de alterações a partir do seu histórico do git, provavelmente precisará considerar:

  • o formato de saída . (ASCII personalizado puro, tipo de registro de alterações Debian, Markdow, ReST ...)
  • alguns filtros de confirmação (você provavelmente não deseja ver todas as alterações de digitação ou cosméticas entrando no seu registro de alterações)
  • alguns confirmam a disputa de texto antes de serem incluídos no changelog. (Garantir a normalização das mensagens como tendo uma primeira letra maiúscula ou um ponto final, mas isso também pode estar removendo algumas marcações especiais no resumo)
  • seu histórico do git é compatível ? Mesclar, etiquetar nem sempre é tão facilmente suportado pela maioria das ferramentas. Depende de como você gerencia seu histórico.

Opcionalmente, você pode querer alguma categorização (coisas novas, alterações, correções) ...

Com tudo isso em mente, eu criei e usei o gitchangelog . Ele visa alavancar uma convenção de mensagens de confirmação do git para atingir todos os objetivos anteriores.

Ter uma convenção de mensagem de confirmação é obrigatório para criar um bom registro de alterações (com ou sem o uso gitchangelog).

confirmar convenção de mensagem

A seguir, sugestões para o que pode ser útil pensar em adicionar suas mensagens de confirmação.

Convém separar aproximadamente seus commits em grandes seções:

  • por intenção (por exemplo: novo, corrigir, alterar ...)
  • por objeto (por exemplo: doc, embalagem, código ...)
  • por público (por exemplo: desenvolvedor, testador, usuários ...)

Além disso, você pode marcar algumas confirmações:

  • como confirmações "menores" que não devem ser exibidas no seu log de alterações (alterações cosméticas, pequenos erros de digitação nos comentários ...)
  • como "refatorar" se você realmente não tiver nenhuma alteração significativa de recurso. Portanto, isso também não deve fazer parte do log de alterações exibido ao usuário final, por exemplo, mas pode ser de algum interesse se você tiver um log de alterações do desenvolvedor.
  • você também pode marcar "api" para marcar alterações na API ou novos itens da API ...
  • ... etc ...

Tente escrever sua mensagem de confirmação direcionando os usuários (funcionalidade) o mais rápido possível.

exemplo

Isso é padrão git log --onelinepara mostrar como essas informações podem ser armazenadas:

* 5a39f73 fix: encoding issues with non-ascii chars.
* a60d77a new: pkg: added ``.travis.yml`` for automated tests. 
* 57129ba new: much greater performance on big repository by issuing only one shell command for all the commits. (fixes #7)
* 6b4b267 chg: dev: refactored out the formatting characters from GIT.
* 197b069 new: dev: reverse ``natural`` order to get reverse chronological order by default. !refactor 
* 6b891bc new: add utf-8 encoding declaration !minor 

Então, se você percebeu, o formato que eu escolhi é:

{new|chg|fix}: [{dev|pkg}:] COMMIT_MESSAGE [!{minor|refactor} ... ]

Para ver um resultado de saída real, você pode olhar o final da página PyPI de gitchangelog

Para ver uma documentação completa da minha convenção de mensagens de confirmação, você pode ver o arquivo de referência gitchangelog.rc.reference

Como gerar um excelente log de alterações a partir disso

Então, é muito fácil criar um registro de alterações completo. Você pode criar seu próprio script rapidamente, ou usargitchangelog .

gitchangelogirá gerar um changelog completo (com suporte a seções como New, Fix...) e é razoavelmente configurável para suas próprias convenções de confirmação. Ele suporta qualquer tipo de saída, graças a templates através Mustache, Mako templatinge tem um motor padrão legado escrito em python matéria; todos os três mecanismos atuais têm exemplos de como usá-los e podem gerar changelogs como o exibido na página PyPI do gitchangelog.

Eu estou certo que você sabe que há uma abundância de outros git logpara changelogferramentas lá fora também.

vaab
fonte
1
Isso é incrível, exatamente o que eu estava procurando. Vou tentar isso, muito obrigado!
Jeff Kiiza
26

Um CHANGELOG mais direto ao ponto. Diga-me se você gosta.

git log --since=1/11/2011 --until=28/11/2011 --no-merges --format=%B
Harshniket Seta
fonte
Este não é um bocado: Eu gostaria de acrescentar outros parâmetros para --format, como explicado no git-scm.com/docs/git-log#_pretty_formats
bluesmonk
23

O gitlog-to-changelogscript é útil para gerar um estilo GNU ChangeLog.

Conforme mostrado por gitlog-to-changelog --help, você pode selecionar os commits usados ​​para gerar um ChangeLogarquivo usando a opção --since:

gitlog-to-changelog --since=2008-01-01 > ChangeLog

ou passando argumentos adicionais depois --, que serão passados ​​para git-log(chamados internamente por gitlog-to-changelog):

gitlog-to-changelog -- -n 5 foo > last-5-commits-to-branch-foo

Por exemplo, estou usando a seguinte regra no nível superior Makefile.amde um dos meus projetos:

.PHONY: update-ChangeLog
update-ChangeLog:
    if test -d $(srcdir)/.git; then                         \
       $(srcdir)/build-aux/gitlog-to-changelog              \
          --format='%s%n%n%b%n' --no-cluster                \
          --strip-tab --strip-cherry-pick                   \
          -- $$(cat $(srcdir)/.last-cl-gen)..               \
        >ChangeLog.tmp                                      \
      && git rev-list -n 1 HEAD >.last-cl-gen.tmp           \
      && (echo; cat $(srcdir)/ChangeLog) >>ChangeLog.tmp    \
      && mv -f ChangeLog.tmp $(srcdir)/ChangeLog            \
      && mv -f .last-cl-gen.tmp $(srcdir)/.last-cl-gen      \
      && rm -f ChangeLog.tmp;                               \
    fi

EXTRA_DIST += .last-cl-gen

Esta regra é usada no momento da liberação para atualizar ChangeLogcom as últimas mensagens de confirmação ainda não gravadas. O arquivo .last-cl-gencontém o identificador SHA1 da confirmação mais recente registrada ChangeLoge é armazenado no repositório Git. ChangeLogtambém é gravado no repositório, para que possa ser editado (por exemplo, para corrigir erros de digitação) sem alterar as mensagens de confirmação.

Roland Levillain
fonte
O script GCC mklog também pode ser interessante: stackoverflow.com/a/31606865/895245
Ciro Santilli郝海东冠状病六四事件法轮功
Este deve ser o projeto vencedor! Por que você não está no github?
Omer Dagan
20

Como criar uma tag por versão é a melhor prática, convém particionar seu log de alterações por versão. Nesse caso, este comando pode ajudá-lo:

git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B
bithavoc
fonte
15

Para projetos GitHub , pode ser útil: github-changelog-generator

Ele gera o log de alterações a partir de questões fechadas de tags e solicitações pull mescladas.

Este CHANGELOG.md foi gerado por este script.

Exemplo:

Changelog

1.2.5 (2015-01-15)

Changelog completo

Aprimoramentos implementados:

  • Use marco para especificar em qual versão o bug foi corrigido # 22

Bugs corrigidos:

  • Erro ao tentar gerar log para repo sem tags # 32

Solicitações pull mescladas:

  • A classe PrettyPrint é incluída usando 'pp' # 43 minúsculo ( schwing )

  • suporte ao github corporativo via opções de linha de comando # 42 ( glenlovett )

skywinder
fonte
Tais projetos são os melhores :) Qual foi a sua motivação para fazer isso? Também graças à sua inspiração, criei uma ferramenta semelhante, que funciona sem rótulos, se divide em Adicionado / Alterado / Fixo / Removido e está em PHP (minha linguagem "nativa"): github.com/Symplify/ChangelogLinker Você escreve posts sobre Changlogs ? Eu gostaria de lê-los
Tomáš Votruba
1
@ TomášVotruba obrigado por palavras calorosas. É apenas o meu hobby. Não postei muito. Mas acho que vale a pena. Muitas felicidades!
skywinder
10

Eu também fiz uma biblioteca para isso. É totalmente configurável com um modelo de bigode. Que pode:

  • Seja armazenado em um arquivo, como CHANGELOG.md .
  • Ser publicado no MediaWiki
  • Ou apenas seja impresso em STDOUT

Eu também fiz:

Mais detalhes no Github: https://github.com/tomasbjerre/git-changelog-lib

Na linha de comando:

npx git-changelog-command-line -std -tec "
# Changelog

Changelog for {{ownerName}} {{repoName}}.

{{#tags}}
## {{name}}
 {{#issues}}
  {{#hasIssue}}
   {{#hasLink}}
### {{name}} [{{issue}}]({{link}}) {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
   {{^hasLink}}
### {{name}} {{issue}} {{title}} {{#hasIssueType}} *{{issueType}}* {{/hasIssueType}} {{#hasLabels}} {{#labels}} *{{.}}* {{/labels}} {{/hasLabels}}
   {{/hasLink}}
  {{/hasIssue}}
  {{^hasIssue}}
### {{name}}
  {{/hasIssue}}

  {{#commits}}
**{{{messageTitle}}}**

{{#messageBodyItems}}
 * {{.}} 
{{/messageBodyItems}}

[{{hash}}](https://github.com/{{ownerName}}/{{repoName}}/commit/{{hash}}) {{authorName}} *{{commitTime}}*

  {{/commits}}

 {{/issues}}
{{/tags}}
"

Ou em Jenkins:

insira a descrição da imagem aqui

Tomas Bjerre
fonte
3
git log --oneline --no-merges `git describe --abbrev=0 --tags`..HEAD | cut -c 9- | sort

É o que eu gosto de usar. Ele recebe todas as confirmações desde a última tag. cutse livra do hash de confirmação. Se você usar números de ticket no início de suas mensagens de confirmação, elas serão agrupadas sort. Classificando Também ajuda se você prefixar certos commits com fix, typo, etc.

orkoden
fonte
3

Deixei o servidor de IC canalizar o seguinte em um arquivo nomeado CHANGELOGpara cada novo release com a data definida no release-filename:

>git log --graph --all --date=relative --pretty=format:"%x09 %ad %d %s (%aN)"
Lorenz Lo Sauer
fonte
2

Para um changelog no estilo GNU, criei a função

gnuc() {
  {
    printf "$(date "+%Y-%m-%d")  John Doe  <[email protected]>\n\n"
    git diff-tree --no-commit-id --name-only -r HEAD | sed 's/^/\t* /'
  } | tee /dev/tty | xsel -b
}

Com isso:

  • Eu comprometo minhas alterações periodicamente para fazer backup e refizê-las antes de fazer a edição final no ChangeLog
  • então corra: gnuc

e agora minha área de transferência contém algo como:

2015-07-24  John Doe  <[email protected]>

        * gdb/python/py-linetable.c (): .
        * gdb/python/py-symtab.c (): .

Então eu uso a área de transferência como ponto de partida para atualizar o ChangeLog.

Não é perfeito (por exemplo, os arquivos devem ser relativos ao caminho do ChangeLog, portanto, python/py-symtab.csem, gdb/desde que editarei o gdb/ChangeLog), mas é um bom ponto de partida.

Scripts mais avançados:

Porém, eu tenho que concordar com Tromey: duplicar dados de confirmação do git no ChangeLog é inútil.

Se você deseja fazer um changelog, faça um bom resumo do que está acontecendo, possivelmente conforme especificado em http://keepachangelog.com/

Ciro Santilli adicionou uma nova foto
fonte
2

Baseado no bithavoc , lista o last tagaté HEAD. Mas espero listar os logs entre 2 tags.

// 2 or 3 dots between `YOUR_LAST_VERSION_TAG` and `HEAD`
git log YOUR_LAST_VERSION_TAG..HEAD --no-merges --format=%B

Listar logs entre 2 tags.

// 2 or 3 dots between 2 tags
git log FROM_TAG...TO_TAG

Por exemplo, ele listará os logs de v1.0.0para v1.0.1.

git log v1.0.0...v1.0.1 --oneline --decorate

AechoLiu
fonte