Buoni modi per gestire un log delle modifiche usando git?


214

Sto usando Git da un po 'di tempo e recentemente ho iniziato a usarlo per taggare le mie versioni in modo da poter tenere più facilmente traccia delle modifiche ed essere in grado di vedere quale versione sono in esecuzione su ciascuno dei nostri clienti (purtroppo il codice attualmente impone che ogni cliente ha la propria copia del sito PHP; lo sto cambiando, ma è lento).

In ogni caso, stiamo iniziando a creare un po 'di slancio, ho pensato che sarebbe stato davvero bello poter mostrare alla gente cosa è cambiato dall'ultima versione. Il problema è che non sto mantenendo un log delle modifiche perché non ho una buona idea di come procedere. Per questo particolare momento, posso scorrere il registro e crearne uno manualmente, ma questo si stancherà molto rapidamente.

Ho provato a cercare su Google "Git Changelog" e "Git Manage Changelog" ma non ho trovato nulla che parlasse davvero del flusso di lavoro delle modifiche al codice e di come coincidesse con il log delle modifiche. Attualmente stiamo seguendo il flusso di lavoro di sviluppo di Rein Henrichs e mi piacerebbe qualcosa che lo accompagnasse.

C'è un approccio standard che mi manca o è un'area in cui ognuno fa le proprie cose?

Grazie mille per i tuoi commenti / risposte!

Risposte:


181

Questo avveniva circa 3-4 anni fa, ma per il bene dei futuri ricercatori, ora è possibile generare registri fantastici con:

git log --oneline --decorate

Oppure, se lo vuoi ancora più bello (con il colore per il terminale):

git log --oneline --decorate --color

Il piping dell'output su ChangeLog è quello che attualmente uso in tutti i miei progetti, è semplicemente fantastico.


4
Un altro tag utile è --graph, che mostra visivamente su quali rami si trovano i commit.
Eruant,

44
Consiglio vivamente di non utilizzare i diff di log dei regali come CHANGELOG: keepachangelog.com
Olivier Lacan

4
la copia git logdell'output nel log delle modifiche non ha senso. Devi avere un lavoro di filtro e modifica per avere un registro delle modifiche leggibile, altrimenti perché dovresti anche avere bisogno di un registro delle modifiche? Penso che tu possa automatizzare la generazione di un log delle modifiche, ma per favore non fare una copia grezza di git log!
vaab

19
Il problema è che, anche supponendo che ogni collaboratore del tuo progetto scriva messaggi di commit chiari e leggibili, continuerai a generare un "log delle modifiche" contenente tonnellate di rumore. I log delle modifiche dovrebbero essere scritti con l'obiettivo di spiegare agli utenti del progetto le notevoli modifiche a loro rilevanti che si sono verificate tra le versioni, mentre i messaggi di commit dovrebbero essere focalizzati sulla spiegazione agli sviluppatori dei miglioramenti apportati al codice dal proprio commit . A volte c'è sovrapposizione lì, ma non sempre.
Ajedi32,

7
Oppure, per renderlo un po 'più concreto, questo metodo creerà un "registro delle modifiche" contenente molte voci come "Corretto l'ortografia di fooMethod in ZModule" e "Refactor XModule per utilizzare la nuova versione di XYLibarary". Ai tuoi utenti non importa . Vogliono sapere quali cambiamenti sono stati fatti dalla loro prospettiva di utenti, non dalla tua prospettiva di sviluppatore. E questo sta perfino ignorando cose come "Unisci PR # 123 da xdev / foo" e "Opps, risolto nuovoFeature in modo che funzioni" tipo cose che potrebbero esistere in qualsiasi repo del mondo reale.
Ajedi32,

60

Puoi usare un po 'di sapore di git log per aiutarti:

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

Se dai un nome ai tuoi rami in modo corretto, in modo che un'unione al master si mostri come qualcosa di simile a "Fobar ramo unito", puoi accorciare le cose mostrando solo quel messaggio e non tutti i piccoli commit che hai unito, che insieme formano il caratteristiche:

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

Potresti essere in grado di aumentarlo con uno script tutto tuo, che potrebbe fare cose come eliminare i bit "Ramo unito", normalizzare la formattazione, ecc. Ad un certo punto devi scriverlo tu stesso, ovviamente.

Quindi è possibile creare una nuova sezione per il log delle modifiche una volta per versione:

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

e lo commetti nella tua versione rilascia il commit.

Se il tuo problema è che quei soggetti impegnati non sono qualcosa di simile a quello che vorresti inserire in un log delle modifiche, hai praticamente due opzioni: continua a fare tutto manualmente (e prova a tenerlo più regolarmente invece di giocare a catch- al momento del rilascio) o correggere lo stile del messaggio di commit. Un'opzione, se i soggetti non lo faranno per te, sarebbe quella di inserire linee come "modifica: aggiunta funzionalità foobar" nei corpi dei tuoi messaggi di commit, in modo che in seguito potresti fare qualcosa di simile git log --pretty=%B | grep ^change:per afferrare solo quei super -importanti bit dei messaggi.

Non sono del tutto sicuro di quanto più di quel git potrebbe davvero aiutarti a creare i tuoi log delle modifiche. Forse ho interpretato male cosa intendi per "gestisci"?


2
È sicuramente un ottimo inizio e non avevo pensato di aggiungere un modificatore al corpo in modo da poterlo seguire in seguito. Potrebbe essere quello che finisco per fare. Grazie per il feedback! Se entro il giorno successivo non arrivano più risposte, segnerò le tue come risposta :-)
Topher Fangio

60

NOTA BENE: sono l'autore di gitchangelog di cui parlerò nel seguito.

TL; DR: potresti voler controllare il log delle modifiche di gitchangelog o l' output ASCII che ha generato il precedente.

Se vuoi generare un log delle modifiche dalla tua cronologia git, probabilmente dovrai considerare:

  • il formato di output . (ASCII personalizzato puro, tipo di log delle modifiche Debian, Markdow, ReST ...)
  • alcuni filtri di commit (probabilmente non vorrai vedere tutti gli errori di battitura o i cambiamenti estetici che entrano nel tuo registro delle modifiche)
  • alcuni commettono il wrangling del testo prima di essere inclusi nel log delle modifiche. (Garantire la normalizzazione dei messaggi con la prima lettera maiuscola o un punto finale, ma potrebbe anche rimuovere alcuni markup speciali nel riepilogo)
  • la tua cronologia git è compatibile ? La fusione, la codifica, non sono sempre così facilmente supportati dalla maggior parte degli strumenti. Dipende da come gestisci la tua cronologia.

Opzionalmente potresti volere un po 'di categorizzazione (cose nuove, modifiche, correzioni di bug) ...

Con tutto ciò in mente, ho creato e usato gitchangelog . Ha lo scopo di sfruttare una convenzione di messaggio git commit per raggiungere tutti gli obiettivi precedenti.

Avere una convenzione con i messaggi di commit è obbligatorio per creare un bel log delle modifiche (con o senza utilizzo gitchangelog).

impegna convenzione messaggio

Di seguito sono riportati alcuni suggerimenti su cosa potrebbe essere utile pensare all'aggiunta nei messaggi di commit.

Potresti voler separare approssimativamente i tuoi commit in grandi sezioni:

  • per intento (ad esempio: nuovo, correzione, modifica ...)
  • per oggetto (ad esempio: doc, packaging, code ...)
  • dal pubblico (ad esempio: sviluppatore, tester, utenti ...)

Inoltre, potresti voler taggare alcuni commit:

  • come commit "minori" che non dovrebbero essere inviati al tuo log delle modifiche (modifiche cosmetiche, piccolo errore di battitura nei commenti ...)
  • come "refattore" se in realtà non sono presenti modifiche significative alle funzioni. Pertanto, ciò non dovrebbe far parte del registro delle modifiche visualizzato all'utente finale, ad esempio, ma potrebbe essere di interesse se si dispone di un registro delle modifiche per gli sviluppatori.
  • puoi anche taggare con "api" per contrassegnare le modifiche API o nuovi elementi API ...
  • ...eccetera...

Prova a scrivere il tuo messaggio di commit indirizzando gli utenti (funzionalità) il più spesso possibile.

esempio

Questo è standard git log --onelineper mostrare come queste informazioni potrebbero essere memorizzate:

* 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 

Quindi, se hai notato, il formato che ho scelto è:

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

Per vedere un risultato di output effettivo, puoi guardare la fine della pagina PyPI di gitchangelog

Per vedere una documentazione completa della mia convenzione sul messaggio di commit puoi vedere il file di riferimento gitchangelog.rc.reference

Come generare un log delle modifiche squisito da questo

Quindi, è abbastanza facile creare un log delle modifiche completo. Potresti creare il tuo script abbastanza rapidamente o usarlo gitchangelog.

gitchangeloggenererà un log delle modifiche completo (con supporto di sezionamento come New, Fix...) ed è ragionevolmente configurabile per le proprie convenzioni di impegno. Supporta qualsiasi tipo di uscita, grazie al templating attraverso Mustache, Mako templatinge ha un motore predefinito legacy scritto in python crudo; tutti gli attuali 3 motori hanno esempi su come usarli e possono emettere il log delle modifiche come quello visualizzato nella pagina PyPI di gitchangelog.

Sono sicuro che so che ci sono un sacco di altri git logper changelogstrumenti là fuori anche.


1
Questo è fantastico, esattamente quello che stavo cercando. Lo proverò, grazie mille!
Jeff Kiiza,


23

Lo gitlog-to-changelogscript è utile per generare uno stile GNU ChangeLog.

Come mostrato da gitlog-to-changelog --help, puoi selezionare i commit usati per generare un ChangeLogfile usando entrambe le opzioni --since:

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

o passando ulteriori argomenti dopo --, che saranno passati a git-log(chiamati internamente da gitlog-to-changelog):

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

Ad esempio, sto usando la seguente regola all'inizio Makefile.amdi uno dei miei progetti:

.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

Questa regola viene utilizzata al momento del rilascio per l'aggiornamento ChangeLogcon gli ultimi messaggi di commit non ancora registrati. Il file .last-cl-gencontiene l'identificatore SHA1 dell'ultimo commit registrato ChangeLoge viene archiviato nel repository Git. ChangeLogviene anche registrato nel repository, in modo che possa essere modificato (ad es. per correggere errori di battitura) senza alterare i messaggi di commit.



Questo dovrebbe essere il progetto vincitore! Perché non ce l'hai su github?
Omer Dagan,

20

Dal momento che la creazione di un tag per versione è la migliore pratica, potresti voler dividere il tuo log delle modifiche per versione. In tal caso, questo comando potrebbe aiutarti:

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

15

Per i progetti GitHub potrebbe essere utile: github-changelog-generator

Genera log delle modifiche da problemi di tag chiusi e richieste pull combinate.

Questo CHANGELOG.md è stato generato da questo script.

Esempio:

changelog

1.2.5 (15-01-2015)

Log completo

Miglioramenti implementati:

  • Usa milestone per specificare in quale versione è stato corretto il bug 22

Bug corretti:

  • Errore durante il tentativo di generare log per repository senza tag # 32

Richieste pull unite:


Tali progetti sono i migliori :) Qual è stata la tua motivazione per farlo? Anche grazie alla tua ispirazione ho creato uno strumento simile, che funziona senza etichette, si divide in Aggiunto / Modificato / Fisso / Rimosso ed è in PHP (la mia lingua "nativa"): github.com/Symplify/ChangelogLinker Scrivi post su Changlogs ? Mi piacerebbe leggerli
Tomáš Votruba,

1
@ TomášVotruba grazie per le belle parole. È solo il mio hobby. Non ho postato molto. Ma penso che ne valga la pena. Auguri!
skywinder,

10

Ho anche creato una biblioteca per questo. È completamente configurabile con un modello Moustache. Che può:

  • Essere archiviati in un file, come CHANGELOG.md .
  • Essere pubblicato su MediaWiki
  • O semplicemente essere stampato su STDOUT

Ho anche fatto:

Maggiori dettagli su Github: https://github.com/tomasbjerre/git-changelog-lib

Dalla riga di 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}}
"

O in Jenkins:

inserisci qui la descrizione dell'immagine


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

È quello che mi piace usare. Riceve tutti i commit dall'ultimo tag. cutelimina l'hash di commit. Se si utilizzano numeri di ticket all'inizio dei messaggi di commit, vengono raggruppati con sort. Ordinamento aiuta anche se si inserisce alcuni impegna con fix, typoecc


3

Lascio che il server CI installi quanto segue in un file denominato CHANGELOGper ogni nuova versione con la data impostata nel nome file release:

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

2

Per un log delle modifiche in stile GNU , ho cucinato la funzione

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

Con questo:

  • Commetto periodicamente le mie modifiche per il backup e le riordinano prima di apportare la modifica finale al ChangeLog
  • quindi eseguire: gnuc

e ora i miei appunti contengono qualcosa come:

2015-07-24  John Doe  <john.doe@gmail.com>

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

Quindi uso gli Appunti come punto di partenza per aggiornare il ChangeLog.

Non è perfetto (ad es. I file dovrebbero essere relativi al loro percorso ChangeLog, quindi python/py-symtab.csenza gdb/da quando lo modificherò gdb/ChangeLog), ma è un buon punto di partenza.

Script più avanzati:

Devo essere d'accordo con Tromey: duplicare i dati di commit git nel ChangeLog è inutile.

Se hai intenzione di creare un log delle modifiche, rendilo un buon riepilogo di ciò che sta succedendo, possibilmente come specificato su http://keepachangelog.com/


2

Basato su bithavoc , elenca il last tagfino a HEAD. Ma spero di elencare i registri tra 2 tag.

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

Elenca i registri tra 2 tag.

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

Ad esempio, elencherà i log da v1.0.0a v1.0.1.

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.