Cara yang baik untuk mengelola changelog menggunakan git?

214

Saya telah menggunakan Git untuk sementara waktu sekarang, dan saya baru-baru ini mulai menggunakannya untuk menandai rilis saya sehingga saya bisa lebih mudah melacak perubahan dan dapat melihat versi mana yang dijalankan masing-masing klien kami (sayangnya kode saat ini diamanatkan bahwa setiap klien memiliki salinan situs PHP mereka sendiri; Saya mengubah ini, tetapi lambat).

Bagaimanapun, kami mulai membangun momentum, saya pikir akan sangat bagus untuk dapat menunjukkan kepada orang-orang apa yang telah berubah sejak rilis terakhir. Masalahnya adalah, saya belum memelihara changelog karena saya tidak punya ide bagus tentang bagaimana melakukannya. Untuk waktu khusus ini, saya dapat menjalankan log dan membuatnya secara manual, tetapi itu akan sangat melelahkan.

Saya mencoba googling "git changelog" dan "git manage changelog" tetapi saya tidak menemukan apa pun yang benar-benar berbicara tentang alur kerja perubahan kode dan bagaimana hal itu bertepatan dengan changelog. Kami saat ini mengikuti alur kerja pengembangan Rein Henrichs dan saya akan menyukai sesuatu yang sejalan dengan itu.

Apakah ada pendekatan standar yang saya lewatkan, atau apakah ini area di mana setiap orang melakukan hal mereka sendiri?

Terima kasih banyak atas komentar / jawaban Anda!

Topher Fangio
sumber

Jawaban:

181

Ini sekitar 3-4 tahun yang lalu, tetapi demi pencari masa depan, sekarang mungkin untuk menghasilkan log yang indah dengan:

git log --oneline --decorate

Atau, jika Anda menginginkannya lebih cantik (dengan warna untuk terminal):

git log --oneline --decorate --color

Memipis output itu ke ChangeLog adalah apa yang saat ini saya gunakan di semua proyek saya, sungguh menakjubkan.


sumber
4
Tag lain yang bermanfaat adalah --graph, yang memperlihatkan secara visual kepada Anda di cabang mana komit itu berada.
Eruant
44
Saya akan sangat menyarankan agar tidak menggunakan diff log hadiah sebagai CHANGELOG: keepachangelog.com
Olivier Lacan
4
menyalin git logoutput ke changelog tidak masuk akal. Anda perlu melakukan pekerjaan penyaringan dan pengeditan untuk memiliki changelog yang dapat dibaca, jika tidak, mengapa Anda bahkan memerlukan changelog? Saya pikir Anda dapat mengotomatiskan pembuatan changelog tapi tolong jangan lakukan salinan mentah git log!
vaab
19
Masalahnya adalah bahwa, bahkan dengan asumsi bahwa setiap kontributor proyek Anda menulis pesan komit yang jelas dan dapat dibaca, Anda masih akan menghasilkan "changelog" yang berisi BANYAK kebisingan. Changelogs harus ditulis dengan tujuan untuk menjelaskan kepada pengguna proyek Anda perubahan penting yang relevan dengan mereka yang terjadi di antara rilis, sedangkan pesan komit harus difokuskan pada menjelaskan kepada pengembang apa perbaikan yang dilakukan komit Anda terhadap kode . Terkadang ada tumpang tindih di sana, tetapi tidak selalu.
Ajedi32
7
Atau, untuk membuatnya sedikit lebih konkret, metode ini akan membuat "log perubahan" yang berisi banyak entri seperti "Memperbaiki ejaan fooMethod dalam ZModule" dan "Refactor XModule untuk menggunakan XYLibarary versi baru". Pengguna Anda tidak peduli tentang itu. Mereka ingin tahu perubahan apa yang dibuat dari perspektif mereka sebagai pengguna, bukan perspektif Anda sebagai pengembang. Dan itu bahkan mengabaikan hal-hal seperti "Gabungkan PR # 123 dari xdev / foo" dan "Opps, perbaiki fitur baru sehingga benar-benar berfungsi" ketik hal-hal yang mungkin ada dalam repo dunia nyata.
Ajedi32
60

Anda dapat menggunakan beberapa rasa log git untuk membantu Anda:

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

Jika Anda memberi nama cabang Anda dengan baik, sehingga gabungan untuk dikuasai muncul sebagai sesuatu seperti "Cabang gabungan fitur-foobar", Anda bisa mempersingkat hal-hal dengan hanya menampilkan pesan itu, dan tidak semua komitmen kecil yang Anda gabungkan, yang bersama-sama membentuk fitur:

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

Anda mungkin dapat menambahkan ini dengan skrip Anda sendiri, yang dapat melakukan hal-hal seperti menghapus bit "Cabang gabungan", menormalkan pemformatan, dll. Pada titik tertentu Anda harus menulisnya sendiri, tentu saja.

Kemudian Anda bisa membuat bagian baru untuk changelog sekali per versi:

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

dan komit di komit rilis versi Anda.

Jika masalah Anda adalah bahwa subjek komit itu tidak seperti apa yang ingin Anda masukkan ke changelog, Anda cukup banyak memiliki dua opsi: tetap melakukan semuanya secara manual (dan mencoba untuk mengikutinya lebih teratur daripada bermain tangkapan) pada waktu rilis), atau perbaiki gaya pesan komit Anda. Salah satu opsi, jika subjek tidak akan melakukannya untuk Anda, akan menempatkan garis seperti "ubah: tambah fitur foobar" di badan pesan komit Anda, sehingga nanti Anda bisa melakukan sesuatu seperti git log --pretty=%B | grep ^change:mengambil hanya super itu bit -penting dari pesan.

Saya tidak sepenuhnya yakin berapa banyak git yang bisa membantu Anda membuat changelog. Mungkin saya salah mengartikan apa yang Anda maksud dengan "kelola"?

Cascabel
sumber
2
Itu jelas merupakan awal yang baik, dan saya tidak berpikir tentang menambahkan pengubah ke tubuh sehingga saya bisa melihatnya nanti. Mungkin itulah yang akhirnya saya lakukan. Terima kasih untuk umpan baliknya! Jika tidak ada lagi jawaban yang masuk pada hari berikutnya atau lebih, saya akan menandai jawaban Anda sebagai :-)
Topher Fangio
60

PENOLAKAN: Saya adalah penulis gitchangelog yang akan saya bicarakan berikut ini.

TL; DR: Anda mungkin ingin memeriksa changelog gitchangelog sendiri atau output ascii yang menghasilkan sebelumnya.

Jika Anda ingin membuat changelog dari sejarah git Anda, Anda mungkin harus mempertimbangkan:

  • yang format output . (ASCII khusus murni, jenis changelog Debian, Markdow, ReST ...)
  • beberapa penyaringan komit (Anda mungkin tidak ingin melihat semua kesalahan ketik atau perubahan kosmetik di changelog Anda)
  • beberapa komit bertengkar sebelum dimasukkan ke changelog. (Memastikan normalisasi pesan memiliki huruf besar pertama atau titik akhir, tetapi bisa juga menghapus beberapa markup khusus dalam ringkasan)
  • apakah riwayat git Anda kompatibel ? Penggabungan, pemberian tag, tidak selalu mudah didukung oleh sebagian besar alat. Itu tergantung pada bagaimana Anda mengelola riwayat Anda.

Secara opsional, Anda mungkin menginginkan beberapa kategorisasi (hal baru, perubahan, perbaikan bug) ...

Dengan semua ini dalam pikiran, saya membuat dan menggunakan gitchangelog . Ini dimaksudkan untuk memanfaatkan konvensi pesan komit git untuk mencapai semua tujuan sebelumnya.

Memiliki konvensi pesan komit wajib untuk membuat changelog yang bagus (dengan atau tanpa menggunakan gitchangelog).

lakukan konvensi pesan

Berikut ini adalah saran untuk apa yang mungkin berguna untuk ditambahkan dalam pesan komit Anda.

Anda mungkin ingin memisahkan kira-kira komitmen Anda menjadi beberapa bagian besar:

  • dengan niat (misalnya: baru, perbaiki, ubah ...)
  • oleh objek (misalnya: doc, packaging, code ...)
  • oleh audiens (misalnya: dev, tester, pengguna ...)

Selain itu, Anda dapat menandai beberapa komitmen:

  • sebagai komitmen "minor" yang seharusnya tidak ditampilkan di changelog Anda (perubahan kosmetik, kesalahan ketik kecil di komentar ...)
  • sebagai "refactor" jika Anda tidak benar-benar memiliki perubahan fitur yang signifikan. Jadi ini seharusnya tidak menjadi bagian dari changelog yang ditampilkan kepada pengguna akhir misalnya, tetapi mungkin menarik jika Anda memiliki changelog pengembang.
  • Anda juga dapat menandai dengan "api" untuk menandai perubahan API atau hal-hal API baru ...
  • ... dll ...

Cobalah untuk menulis pesan komit Anda dengan menargetkan pengguna (fungsionalitas) sesering mungkin.

contoh

Ini standar git log --onelineuntuk menunjukkan bagaimana informasi ini dapat disimpan ::

* 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 

Jadi jika Anda perhatikan, format yang saya pilih adalah:

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

Untuk melihat hasil keluaran aktual, Anda bisa melihat di akhir halaman PyPI dari gitchangelog

Untuk melihat dokumentasi lengkap dari konvensi pesan komit saya, Anda dapat melihat file referensi gitchangelog.rc.reference

Cara menghasilkan changelog yang sangat bagus dari ini

Kemudian, sangat mudah untuk membuat changelog lengkap. Anda dapat membuat skrip Anda sendiri dengan cepat, atau menggunakannyagitchangelog .

gitchangelogakan menghasilkan log perubahan lengkap (dengan dukungan pembagian sebagai New, Fix...), dan dapat dikonfigurasi secara wajar untuk konvensi yang Anda buat sendiri. Mendukung jenis output berkat template melalui Mustache, Mako templatingdan memiliki mesin standar warisan yang ditulis dalam python baku; semua 3 mesin saat ini memiliki contoh cara menggunakannya dan dapat menampilkan changelog's seperti yang ditampilkan di halaman PyPI dari gitchangelog.

Saya yakin Anda tahu bahwa ada banyak lainnya git loguntuk changelogalat di luar sana juga.

vaab
sumber
1
Ini luar biasa, persis apa yang saya cari. Saya akan coba ini, terima kasih banyak!
Jeff Kiiza
26

Lebih ke intinya CHANGELOG. Katakan padaku jika kalian suka.

git log --since=1/11/2011 --until=28/11/2011 --no-merges --format=%B
Harshniket Seta
sumber
Ini agak melakukannya: Saya akan menambahkan parameter lain --format, seperti yang dijelaskan dalam git-scm.com/docs/git-log#_pretty_formats
bluesmonk
23

The gitlog-to-changelogScript berguna untuk menghasilkan GNU-gaya ChangeLog.

Seperti yang ditunjukkan oleh gitlog-to-changelog --help, Anda dapat memilih komit yang digunakan untuk membuat ChangeLogfile menggunakan salah satu opsi --since:

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

atau dengan memberikan argumen tambahan setelahnya --, yang akan diteruskan ke git-log(dipanggil secara internal oleh gitlog-to-changelog):

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

Misalnya, saya menggunakan aturan berikut di tingkat atas Makefile.amdari salah satu proyek saya:

.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

Aturan ini digunakan pada waktu rilis untuk memperbarui ChangeLogdengan pesan komit terbaru yang belum direkam. File tersebut .last-cl-genberisi pengidentifikasi SHA1 dari komit terbaru yang direkam ChangeLogdan disimpan dalam repositori Git. ChangeLogjuga direkam dalam repositori, sehingga dapat diedit (misalnya untuk memperbaiki kesalahan ketik) tanpa mengubah pesan komit.

Roland Levillain
sumber
Skrip mklog GCC mungkin juga menarik: stackoverflow.com/a/31606865/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Ini harus menjadi proyek yang menang! Mengapa Anda tidak memilikinya di github?
Omer Dagan
20

Karena membuat tag per versi adalah praktik terbaik, Anda mungkin ingin mempartisi changelog Anda per versi. Dalam hal ini, perintah ini dapat membantu Anda:

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

Untuk proyek GitHub mungkin berguna: github-changelog-generator

Ini menghasilkan changelog dari masalah tag tertutup, dan menggabungkan permintaan tarik.

Ini CHANGELOG.md dihasilkan oleh script ini.

Contoh:

Changelog

1.2.5 (2015-01-15)

Changelog Penuh

Peningkatan yang diterapkan:

  • Gunakan tonggak untuk menentukan di mana bug versi diperbaiki # 22

Memperbaiki bug:

  • Kesalahan saat mencoba membuat log untuk repo tanpa tag # 32

Permintaan tarikan yang digabungkan:

  • Kelas PrettyPrint disertakan menggunakan huruf kecil 'pp' # 43 ( schwing )

  • dukung perusahaan github melalui opsi baris perintah # 42 ( glenlovett )

pencukur langit
sumber
Proyek-proyek seperti itu adalah yang terbaik :) Apa motivasi Anda untuk melakukannya? Juga berkat inspirasi Anda, saya membuat alat serupa, yang berfungsi tanpa label, terbagi menjadi Ditambahkan / Diubah / Diperbaiki / Dihapus dan dalam PHP (bahasa "asli" saya): github.com/Symplify/ChangelogLinker Anda menulis posting tentang Changlog ? Saya ingin membacanya
Tomáš Votruba
1
@ TomášVotruba terima kasih atas kata-kata hangat. Itu hanya hobi saya. Saya tidak memposting banyak. Tapi saya pikir itu sepadan. Semoga sukses!
Pencakar langit
10

Saya juga membuat perpustakaan untuk ini. Ini sepenuhnya dapat dikonfigurasi dengan template Moustache. Yang dapat:

Saya juga membuat:

Lebih detail tentang Github: https://github.com/tomasbjerre/git-changelog-lib

Dari baris perintah:

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}}
"

Atau di Jenkins:

masukkan deskripsi gambar di sini

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

Apa yang saya suka gunakan. Itu mendapatkan semua komitmen sejak tag terakhir. cutmenyingkirkan hash komit. Jika Anda menggunakan nomor tiket di awal pesan komit Anda, mereka dikelompokkan dengan sort. Menyortir juga membantu jika Anda awalan komit tertentu dengan fix, typo, dll

orkoden
sumber
3

Saya membiarkan server CI menyalurkan berikut ini ke file bernama CHANGELOGuntuk setiap rilis baru dengan tanggal yang ditetapkan dalam nama file rilis:

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

Untuk changelog gaya GNU , saya telah memasak fungsinya

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
}

Dengan ini:

  • Saya melakukan perubahan saya secara berkala untuk membuat cadangan dan rebase sebelum melakukan edit terakhir ke ChangeLog
  • lalu lari: gnuc

dan sekarang clipboard saya berisi sesuatu seperti:

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

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

Lalu saya menggunakan clipboard sebagai titik awal untuk memperbarui ChangeLog.

Itu tidak sempurna (misalnya file harus relatif terhadap jalur ChangeLog mereka, jadi python/py-symtab.ctanpa gdb/karena saya akan mengedit gdb/ChangeLog), tetapi merupakan titik awal yang baik.

Skrip lebih lanjut:

Saya harus setuju dengan Tromey: menduplikasi data git commit di ChangeLog tidak berguna.

Jika Anda ingin membuat changelog, buatlah ringkasan yang bagus tentang apa yang sedang terjadi, mungkin seperti yang ditentukan di http://keepachangelog.com/

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
2

Berdasarkan bithavoc , daftar last tagsampai HEAD. Tapi saya berharap daftar log antara 2 tag.

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

Daftar log antara 2 tag.

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

Misalnya, ia akan mendaftar log dari v1.0.0ke v1.0.1.

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

AechoLiu
sumber