{"id":13437558,"url":"https://github.com/saschagrunert/git-journal","last_synced_at":"2025-05-15T23:03:00.509Z","repository":{"id":37335004,"uuid":"64057776","full_name":"saschagrunert/git-journal","owner":"saschagrunert","description":"The Git Commit Message and Changelog Generation Framework :book:","archived":false,"fork":false,"pushed_at":"2023-01-20T23:42:33.000Z","size":2409,"stargazers_count":622,"open_issues_count":25,"forks_count":16,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-15T23:01:57.140Z","etag":null,"topics":["commit-conventions","git","git-journal","journal"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saschagrunert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-24T09:14:56.000Z","updated_at":"2025-04-28T04:29:38.000Z","dependencies_parsed_at":"2023-02-12T06:46:30.715Z","dependency_job_id":null,"html_url":"https://github.com/saschagrunert/git-journal","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschagrunert%2Fgit-journal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschagrunert%2Fgit-journal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschagrunert%2Fgit-journal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saschagrunert%2Fgit-journal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saschagrunert","download_url":"https://codeload.github.com/saschagrunert/git-journal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254436943,"owners_count":22070946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commit-conventions","git","git-journal","journal"],"created_at":"2024-07-31T03:00:58.284Z","updated_at":"2025-05-15T23:03:00.445Z","avatar_url":"https://github.com/saschagrunert.png","language":"Rust","funding_links":[],"categories":["Development tools","Rust","git"],"sub_categories":["Web Servers","Workflow Automation"],"readme":"# git-journal 📖\n[![Build Status](https://travis-ci.org/saschagrunert/git-journal.svg)](https://travis-ci.org/saschagrunert/git-journal) [![Build status](https://ci.appveyor.com/api/projects/status/ay7punrihpjid3vj?svg=true)](https://ci.appveyor.com/project/saschagrunert/git-journal) [![Coverage Status](https://coveralls.io/repos/github/saschagrunert/git-journal/badge.svg?branch=master)](https://coveralls.io/github/saschagrunert/git-journal?branch=master) [![dependency status](https://deps.rs/repo/github/saschagrunert/git-journal/status.svg)](https://deps.rs/repo/github/saschagrunert/git-journal) [![Crates.io](https://img.shields.io/crates/v/git-journal.svg)](https://crates.io/crates/git-journal) [![doc.rs](https://docs.rs/git-journal/badge.svg)](https://docs.rs/git-journal) [![master doc gitjournal](https://img.shields.io/badge/master_doc-gitjournal-blue.svg)](https://saschagrunert.github.io/git-journal) [![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/saschagrunert/git-journal/blob/master/LICENSE) [![Join the chat at https://gitter.im/git-journal/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/git-journal/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n## The Git Commit Message and Changelog Generation Framework\n\nTable of contents:\n\n* [TL;DR](#tldr)\n* [Installation](#installation)\n* [Usage](#usage)\n    * [Default output](#default-output)\n    * [Template output](#template-output)\n    * [Commit message preparation and verification](#commit-message-preparation-and-verification)\n* [Current Features](#current-features)\n* [Planned features and improvements](#planned-features-and-improvements)\n* [Contributing](#contributing)\n\n---\n\n\u003cimg src=\"./.github/example.jpg\" align=\"right\" width=\"500px\"\u003e\n\n## TL;DR\n[tldr]: #tldr\n\nMaintaining changelogs can be time-consuming, especially when multiple persons work on the same project. If you maintain\na separate file, merge conflicts and additional release work is sure to follow.\n\nSometimes complete entries are lost during merge conflict resolution, people forget to mention something or links\nbetween issues and actual commits are missing.\n\nIt would be great, if we could use the commit history of [git](https://git-scm.com/) to generate a *beautiful* changelog\nwithout any additional work needed.\n\n**This is where git-journal jumps in.**\n\nTo ensure this auto-generation a framework to write more sensible commit messages is needed. Single commit messages\nshould contain one logical change of the project which is described in a standardized way. This results in a much\ncleaner git history and provides contributors more information about the actual change.\n\nThe theoretical base consists of two RFCs:\n\n* [RFC0001 for the commit message syntax extension](https://github.com/saschagrunert/git-journal/blob/master/rfc/0001-commit-msg.md)\n* [RFC0002 for the output templating engine](https://github.com/saschagrunert/git-journal/blob/master/rfc/0002-output-templating.md)\n\n## Installation\n[installation]: #installation\n\nTo use _git-journal_ as a git extension a [Rust installation](https://www.rust-lang.org/en-US/downloads.html) is needed\nincluding the package manager [cargo](https://crates.io/install). Different package managers will provide these as well,\nfor example via [Pacman](https://wiki.archlinux.de/title/pacman) on Arch Linux:\n\n```terminal\nsudo pacman -S rust cargo\n```\n\nFor a super easy installation it is also possible to use [rustup](https://rustup.rs/). Once these two dependencies are installed, _git-journal_ can be installed via:\n\n```terminal\ncargo install git-journal\n```\n\nAfter adapting your `$PATH` variable to search also within `~/.cargo/bin` it should be possible to run it by invoking\n`git journal`.\n\n## Usage\n[usage]: #usage\n\nThe binary `git-journal` depends on the Rust library `gitjournal`, which also can be used independently from the binary\napplication to write customized solutions. [This repository](https://github.com/saschagrunert/test) will be used as an\nexample for the following explanations.\n\n### Default output\n[defaultoutput]: #defaultoutput\n\nIf you run `git journal` anywhere inside this repository, the output will be a nice looking\n[Markdown](https://en.wikipedia.org/wiki/Markdown) formatted changelog based on your repositories git log:\n\n```terminal\n\u003e git journal\n[git-journal] [INFO] Skipping commit: Summary parsing: 'Merge branch 'test_branch''\n[git-journal] [OKAY] Parsing done.\n\n# Unreleased (2016-09-18):\n- [Added] file4 again\n    This paragraph explains the change in detail\n    - [Fixed] multiple issues\n    - [Removed] not needed things\n- [Removed] file4.txt\n- [Added] file4.txt\n- [Added] file1.txt again\n- [Removed] file1.txt\n\nFixes:\n#1, #2\n\n# v2 (2016-09-12):\n- [Added] file3.txt\n\n```\n\nAll commits are sorted by time, which means that the newest elements occur at the top. The parsing of the commit message\nwill be done regarding [RFC0001](https://github.com/saschagrunert/git-journal/blob/master/rfc/0001-commit-msg.md), which\ndescribes the different syntax elements within a commit message. Categories (`[Added]`, `[Fixed]`, ...) are\nautomatically wrapped in square brackets if available. It is also possible to define own categories within the\nconfiguration file. The journal automatically lists the log from the last release and the unreleased entries.\n\nThe footers of the commit messages (described in RFC0001) are automatically accumulated and printed after the changelog\nlist ordered by their values. It is also possible to skip the unreleased entries:\n\n```terminal\n\u003e git journal -u\n[git-journal] [OKAY] Parsing done.\n\n# v2 (2016-09-12):\n- [Added] file3.txt\n```\n\nUsing a specific commit range in the format `REV..REV` or a different starting point than `HEAD` for parsing can also\nbe done:\n\n```terminal\n\u003e git journal v1\n\u003e git journal v2\n\u003e git journal v1...HEAD^\n```\n\nIt is also possible to print all releases (git tags) with `-a`, the past `n` releases via `-n \u003cCOUNT\u003e`:\n\n```terminal\n\u003e git journal -a\n[git-journal] [INFO] Skipping commit: Summary parsing: 'Merge branch 'test_branch''\n[git-journal] [OKAY] Parsing done.\n\n# Unreleased (2016-09-18):\n- [Added] file4 again\n    This paragraph explains the change in detail\n    - [Fixed] multiple issues\n    - [Removed] not needed things\n- [Removed] file4.txt\n- [Added] file4.txt\n- [Added] file1.txt again\n- [Removed] file1.txt\n\n# v2 (2016-09-12):\n- [Added] file3.txt\n\n# v1 (2016-09-12):\n- [Added] file2.txt\n- [Added] file1.txt\n```\n\n```terminal\n\u003e git journal -un1\n[git-journal] [OKAY] Parsing done.\n\n# v2 (2016-09-12):\n- [Added] file3.txt\n```\n\nBeside the usual detailed log a short version (`-s`) exists, which just uses the commit summary:\n\n```terminal\n\u003e git journal -as\n[git-journal] [INFO] Skipping commit: Summary parsing: 'Merge branch 'test_branch''\n[git-journal] [OKAY] Parsing done.\n\n# Unreleased (2016-09-18):\n- [Added] file4 again\n- [Removed] file4.txt\n- [Added] file4.txt\n- [Added] file1.txt again\n- [Removed] file1.txt\n\n# v2 (2016-09-12):\n- [Added] file3.txt\n\n# v1 (2016-09-12):\n- [Added] file2.txt\n- [Added] file1.txt\n```\n\nIt also possible to append the output of the journal to a file (`-o`), which will be separated by a newline (`---`) for\neach git journal invocation. Git tags with a specific patterns like `rc` will be excluded automatically, which can be\ncustomized via `-e`.\n\nFor more information please refer to the help `git journal -h`.\n\n### Template output\n[templateoutput]: #templateoutput\n\nThe design of commit message templates is described in\n[RFC0002](https://github.com/saschagrunert/git-journal/blob/master/rfc/0002-output-templating.md). From now on we are\nusing this template for the test repository:\n\n```toml\n[[tag]]\ntag = \"default\"\nname = \"Default\"\n\n[[tag]]\ntag = \"tag1\"\nname = \"Section 1\"\n\n[[tag]]\n[[tag.subtag]]\ntag = \"tag2\"\nname = \"Subsection 1\"\nfooters = [\"Fixes\"]\n```\n\nTo use such a template just use the `-t` option:\n\n```terminal\n\u003e git journal -t CHANGELOG.toml\n[git-journal] [INFO] Skipping commit: Summary parsing: 'Merge branch 'test_branch''\n[git-journal] [OKAY] Parsing done.\n\n# Unreleased (2016-09-21):\n## Default\n- [Removed] file3.txt\n- [Removed] file4.txt\n- [Removed] file5.txt\n- [Added] new .gitjournal\n- [Improved] file5.txt\n- [Fixed] this\n- [Removed] that\n- [Added] .gitjournal.toml file\n- [Removed] not needed things\n- [Removed] file4.txt\n- [Added] file4.txt\n- [Added] file1.txt again\n- [Removed] file1.txt\n\n## Section 1\n- [Added] file4 again\n- This paragraph explains the change in detail\n\n### Subsection 1\n- [Fixed] multiple issues\n\nFixes:\n#1, #2, #1, #2, #3, #5, #6, #7\n\n# v2 (2016-09-12):\n## Default\n- [Added] file3.txt\n```\n\nEverything which is untagged will go into the `default` section. The name of `tag1` will be mapped to `Section 1` and\n`tag2` is a subtag of `tag1` (see the markdown header). This also means that it is now possible that list items are\nuncategorized since the templating engine gives the possibility to split commits into multiple pieces. Parsed paragraphs\nare converted to single list items to always provide a clean markdown. The footers are specified as an toml array of\nstrings which will output the selected footer keys at the correct position of the log. Please consider that the\naccumulation of the footers are related to the complete tag, not just the section where there printed. Other command\nline options like in the default output are available as well.\n\nIt is also possible to add a custom header or footer text to every output or every tag. For more information please read\n[RFC0002](https://github.com/saschagrunert/git-journal/blob/master/rfc/0002-output-templating.md).\n\n### Commit message preparation and verification\n[prepverify]: #prepverify\n\nTo use the automatic commit message preparation and verification the git journal setup has to be executed on every local\nrepository:\n\n```terminal\n\u003e git journal setup\n[git-journal] [OKAY] Defaults written to '.gitjournal.toml' file.\n[git-journal] [OKAY] Git hook installed to '.git/hooks/commit-msg'.\n[git-journal] [OKAY] Git hook installed to '.git/hooks/prepare-commit-msg'.\n[git-journal] [OKAY] Installed bash completions to the path.\n[git-journal] [OKAY] Installed fish completions to the path.\n[git-journal] [OKAY] Installed zsh completions to the path.\n```\n\nIf there already exists these hooks _git-journal_ tries to append the needed commands, which has to be verified by hand\nafterwards. The generated command line completions for bash and fish needs to be put in the correct directory of your\nshell. The default configuration file is a [toml](https://github.com/toml-lang/toml) file which represents\n[this structure](https://saschagrunert.github.io/git-journal/gitjournal/config/struct.Config.html). A default\nconfiguration with comments can also be\n[found here](https://saschagrunert.github.io/git-journal/gitjournal/struct.GitJournal.html#examples-1).\n\nIf the setup is done _git-journal_ will verify your inserted commit message as well as doing a commit message\npreparation. For example, if we are now trying to commit something which can not be parsed:\n\n```terminal\n\u003e touch my_file\n\u003e git add my_file\n\u003e git commit -m \"This commit contains no cactegory\"\n[git-journal] [ERROR] Commit message preparation failed: GitJournal: Parser: Summary parsing: 'This commit contains no cactegory'\n```\n\nSince we are using the `-m` flag there is no chance for the user to edit the message any more and _git-journal_ will\nreject it. If we are using a commit message editor via the usual `git commit` without the `-m` we will get a default\ncommit message template:\n\n```terminal\nJIRA-1234 Added ...\n\n# Add a more detailed description if needed\n\n# - Added ...\n# - Changed ...\n# - Fixed ...\n# - Improved ...\n# - Removed ...\n```\n\nThe `JIRA-1234` prefix is just the default and can be configured via the `.gitjournal.toml` file. If the submitted\ncommit message is also invalid we will get an error like this:\n\n```terminal\n[git-journal] [ERROR] Commit message invalid: GitJournal: Parser: Summary parsing: 'This commit message is also invalid'\n```\n\nIf everything went fine it should look like this:\n```terminal\n\u003e git commit -m \"Added my_file\"\n[git-journal] [OKAY] Commit message prepared.\n[git-journal] [OKAY] Commit message valid.\n[master 1b1fcad] Added my_file\n 1 file changed, 0 insertions(+), 0 deletions(-)\n create mode 100644 my_file\n```\n\nIf a default template is configured then _git-journal_ will also check the available tags of the template against your\ncommit message tags. So there will be an error if one of the tags within the commit message is not available within the\ndefined template:\n\n```terminal\n[git-journal] [WARN] These tags are not part of the default template: 'tag1'.\n[git-journal] [ERROR] Commit message invalid: GitJournal: Verify: Not all tags exists in the default template.\n```\nThis means in detail that _git-journal_ will build up two gates (one for preparation and one for verification) during\ndoing the commit by the user. This graphic will sum up where _git-journal_ will take influence on the local git\nrepository:\n\u003cimg src=\"./.github/flow.png\" width=\"100%\"\u003e\n\n## Current Features\n[features]: #features\n\n* **General**\n    * [x] Generation of completions for bash, fish and zsh shell during setup.\n    * [x] Custom category support for commit preparation, validation and output (`categories`).\n    * [x] Automatic multi threading support for the parsing.\n* **Journal generation and output**\n    * [x] Automatic up-level repository search if a sub path of a git repository was specified.\n    * [x] Custom commit ranges or different git commit starting points for parsing.\n    * [x] Run in a different specified path than the current working directory (`-p`).\n    * [x] Parse and print the complete history (`-a`) or the past `n` releases (`-n`).\n    * [x] Print a short version of the commit history based on the commit message summary (`-s`).\n    * [x] Output the parsed log in valid Markdown to the command line or a file (`-o`).\n    * [x] Custom git tag exclude pattern, e.g. `rc` tags (`-e`).\n    * [x] Enable/Disable debug message output (`enable_debug`).\n    * [x] Enable/Disable colored output via the command line (`colored_output`).\n    * [x] Automatic wrapping of commit message categories in square brackets.\n    * [x] Templating support including tag and name mapping (`default_template`).\n    * [x] Support for accumulating footer data (also for templating engine).\n    * [x] Different sorting methods (`\"date\"` and `\"name\"`) for the default and template based output (`sort_by`).\n    * [x] Support for custom header and footer fields within templates with multiple or single output.\n    * [x] Generation of default templates based on the parsing results (`-g`).\n    * [x] Commit hash links for commits in standard and template output (`show_commit_hash`).\n    * [x] Support for custom category delimiters (`category_delimiters`).\n* **Preparation and Verification of commit messages**\n    * [x] Automatic installation of git hooks inside the local repository.\n    * [x] Generation of default configuration file during setup.\n    * [x] Commit message validation based on implemented parser.\n    * [x] Message preparation with custom commit prefix (`template_prefix`).\n    * [x] Differentiation between amended and new commits.\n    * [x] Use the tags from the default template for the commit message verification.\n\n## Planned features and improvements\n[planned]: #planned\n\n* There are no bigger features planned yet.\n\n## Contributing\n[contributing]: #contributing\n\nYou want to contribute to this project? Wow, thanks! So please just fork it and send me a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaschagrunert%2Fgit-journal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaschagrunert%2Fgit-journal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaschagrunert%2Fgit-journal/lists"}