File: usage.md

package info (click to toggle)
git-changelog 2.7.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 612 kB
  • sloc: python: 4,026; makefile: 33; javascript: 13
file content (941 lines) | stat: -rw-r--r-- 33,775 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
---
hide:
- navigation
---

# Usage

*git-changelog* parses your commit messages to extract useful data
that is then rendered using Jinja2 templates, for example to
a changelog file formatted in Markdown.

Each Git tag will be treated as a version of your project.
Each version contains a set of commits, and will be an entry
in your changelog. Commits in each version will be grouped
by sections, depending on the commit coonvention you follow.

## Quick usage

Print the changelog on standard output,
using the basic convention for commit messages
and the Angular template:

```bash
git-changelog -c basic -t angular
```

Update a changelog in-place, overwriting and updating the "Unreleased" section,
using the Angular commit message convention and the Keep A Changelog template (default):

```bash
git-changelog -io CHANGELOG.md -c angular
```

Same thing, but now you're ready to tag so you tell *git-changelog*
to guess the new version by bumping the latest version
based on the semantics of your commits:

```bash
git-changelog -B auto -io CHANGELOG.md -c angular
```

Same thing, but also parse Git trailers
and choose the sections to render, and their order
(author's favorite!):

```bash
git-changelog -B auto -Tio CHANGELOG.md -c angular -s build,deps,fix,feat,refactor
```

Or include all available sections for the convention:

```bash
git-changelog -B auto -Tio CHANGELOG.md -c angular -s :all:
```

Generate a changelog using a custom template,
and parsing provider-specific references (GitHub/GitLab/Bitbucket):

```bash
git-changelog -rt path:./templates/changelog.md.jinja
```

Generate a changelog using a specific provider (GitHub/GitLab/BitBucket):

```bash
git-changelog --provider github
```

Author's favorite, from Python:

```python
from git_changelog.cli import build_and_render

build_and_render(
    repository=".",
    output="CHANGELOG.md",
    convention="angular",
    provider="github",
    template="keepachangelog",
    parse_trailers=True,
    parse_refs=False,
    sections=("build", "deps", "feat", "fix", "refactor"),
    versioning="pep440",
    bump="auto",
    in_place=True,
)
```

The following sections explain in more details all the features of *git-changelog*.

## Configuration files

[(--config-file)](cli.md#config_file)

Project-wise, permanent configuration of *git-changelog* is possible.
By default, *git-changelog* will search for the existence a suitable configuration
in the `pyproject.toml` file or otherwise, the following configuration files
in this particular order:

- `.git-changelog.toml`
- `config/git-changelog.toml`
- `.config/git-changelog.toml`
- `<current-user-config-path>/git-changelog.toml`

In the last case (`<current-user-config-path>/git-changelog.toml`), the `<current-user-config-path>`
is platform-dependent and will be automatically inferred from your settings.
In Unix systems, this will typically point at `$HOME/.config/git-changelog.toml`.
The use of a configuration file can be disabled or overridden with the `--config-file`
option.
To disable the configuration file, pass `no`, `none`, `false`, `off`, `0` or empty string (`''`):

```bash
git-changelog --config-file no
```

To override the configuration file, pass the path to the new file:

```bash
git-changelog --config-file $HOME/.custom-git-changelog-config
```

The configuration file must be written in TOML language, and may take values
for most of the command line options:

```toml
bump = "auto"
convention = "basic"
in-place = false
include-all = false
filter-commits = "0.5.0.."
marker-line = "<!-- insertion marker -->"
output = "output.log"
parse-refs = false
parse-trailers = false
provider = "gitlab"
repository = "."
sections = ["fix", "maint"]
template = "angular"
version-regex = "^## \\\\[(?P<version>v?[^\\\\]]+)"
versioning = "semver"
zerover = true
```

In the case of configuring *git-changelog* within `pyproject.toml`, these
settings must be found in the appropriate section:

```toml
[tool.git-changelog]
bump = "minor"
convention = "conventional"
in-place = false
include-all = false
filter-commits = "0.5.0.."
marker-line = "<!-- insertion marker -->"
output = "output.log"
parse-refs = false
parse-trailers = false
provider = "gitlab"
repository = "."
sections = "fix,maint"
template = "keepachangelog"
version-regex = "^## \\\\[(?P<version>v?[^\\\\]]+)"
versioning = "semver"
zerover = true
```

## Output a changelog

[(--output)](cli.md#output)

To output a changelog for the current repository (current directory),
simply run:

```bash
git-changelog
```

To output a changelog for another repository (directory),
pass the path to that repository:

```bash
git-changelog /path/to/my/repo
```

By default, *git-changelog* will parse commit messages
as if they use the "basic" convention, and render a
[Keep A Changelog][keepachangelog]-formatted changelog
writing to the standard output.

To write to a file instead, use the `-o` or `--output` CLI option:

```bash
git-changelog --output CHANGELOG.md
```

## Choose the commit message convention

[(--convention)](cli.md#convention)

Different conventions, or styles, are supported by *git-changelog*.
To select a different convention than the default one (basic, see below),
use the `-c` or `--convention` CLI option:

```bash
git-changelog --convention angular
```

### Basic convention

The basic convention, as the name implies, is very simple.
If a commit message summary (the first line of the message)
starts with a particular word/prefix (case-insensitive),
it is added to the corresponding section:

Type     | Section
---------|-----------
`add`    | Added
`fix`    | Fixed
`change` | Changed
`remove` | Removed
`merge`  | Merged
`doc`    | Documented

### Angular/Karma convention

The Angular/Karma convention initiated the [Conventional Commit specification][conventional-commit].
It expects the following format for commit messages:

```text
<type>[optional scope]: <description>

[optional body]

[optional footer]
```

The types and corresponding sections *git-changelog* recognizes are:

Type         | Section
-------------|-------------------------
`build`      | Build
`chore`      | Chore
`ci`         | Continuous Integration
`deps`       | Dependencies
`doc(s)`     | Docs
`feat`       | Features
`fix`        | Bug Fixes
`perf`       | Performance Improvements
`ref(actor)` | Code Refactoring
`revert`     | Reverts
`style`      | Style
`test(s)`    | Tests

Breaking changes are detected by searching for `^break(s|ing changes?)?[ :]`
in the commit message body.

### Conventional Commit convention

The [Conventional Commit specification][conventional-commit] originates
from the Angular commit message convention. It's basically the same thing,
but only the `feat` and `fix` types are specified, and the rest is up to you.
In *git-changelog* though, it is equivalent to the Angular convention,
with an additional thing: it detects breaking changes when `!`
appears right before the colon in the message summary
(for example: `refactor!: Stuff`).

## Choose the sections to render

[(--sections)](cli.md#sections)

Each commit message convention has a default set of sections
that will be rendered in the output. The other sections will be ignored.
To override this, you can provide a list of sections to render to *git-changelog*
with the `-s` or `--sections` CLI option:

```bash
# with the basic convention
git-changelog --sections add,fix,remove,doc

# with the angular/karma/conventionalcommit convention
git-changelog --sections build,deps,feat,fix,refactor
```

You can also use the special value `:all:` to include all available sections
for the selected convention:

```bash
# include all sections for the angular convention
git-changelog --convention angular --sections :all:
```

This is particularly useful when you want to see all commit types in your changelog
without having to list them explicitly.

See the previous paragraphs to get the list of available sections
for each commit message convetions.

## Include non-conventional commits

[(--include-all)](cli.md#include_all)

By default, *git-changelog* only includes commits that match the configured
commit message convention. Commits that don't follow the convention (e.g., random
commit messages like "fix typo", "wip", or "update stuff") are silently filtered out.

If you want to include **all commits** in your changelog, even those that don't
follow the convention, use the `-a` or `--include-all` CLI option:

```bash
git-changelog --include-all
```

Non-conventional commits will be rendered in a "Misc" section at the end of each version.
This is particularly useful for:

- Projects with mixed commit styles or during transitions to conventional commits
- Ensuring a complete history of all changes, not just the conventional ones
- Debugging or reviewing what commits were made in a version

Example configuration in a TOML file:

```toml
convention = "angular"
include-all = true
```

When combined with the `--sections` option, the "Misc" section will appear
after all specified sections:

```bash
git-changelog --sections feat,fix --include-all
# Renders: Features, Bug Fixes, Misc
```

## Choose a changelog template

[(--template)](cli.md#template)

*git-changelog* provides two built-in templates: `keepachangelog` and `angular`.
Both are very similar, they just differ with the formatting a bit.
We stronly recommend the `keepachangelog` format.

Use the `-t`, `--template` option to specify the template to use:

```bash
git-changelog --template keepachangelog
```

You can also write and use your own changelog templates.
Templates are single files written using the [Jinja][jinja] templating engine.
You can get inspiration from
[the source of our built-in templates][builtin-templates].

Prefix the value passed to the `--template` option with `path:` to use a custom template:

```bash
git-changelog --template path:mytemplate.md
```

### Writing a changelog template

To write your own changelog template,
we recommend using our [keepachangelog built-in template][keepachangelog-template]
as a starting point.

From there, simply modify the different Jinja macros:

- `render_commit()`, which accepts a [Commit][git_changelog.Commit] object
- `render_section()`, which accepts a [Section][git_changelog.Section] object
- `render_version()`, which accepts a [Version][git_changelog.Version] object

Then, also update the template at the end, to change the changelog's header
or add a changelog footer for example.

The variables available in the template are `changelog`,
which is a [Changelog][git_changelog.Changelog] instance,
and `in_place`, which is a boolean, and tells whether the changelog
is being updated in-place.

> QUESTION: **How to get spacing right?**
> Although spacing (line jumps) is not super important in Markdown contents
> (it won't change HTML output), it is best if you get spacing right,
> as it makes prettier changelog files, and will reduce the noise
> in diffs when you commit an update to your changelog.
>
> To manage spacing (in Jinja terms, [control whitespace][control-whitespace])
> Jinja allows to "eat" spaces on the left or right of an expression,
> by adding a dash after/before the percent sign: `{%-` and `-%}`.
> However, spacing is not always easy to get right with Jinja,
> so here are two tips that we find helpful:
>
> - **To collapse content up**, eat spaces on the **left**, and add new lines
>     at the **top** of the Jinja block:
>
>     ```django
>     Some text.
>     {%- if some_condition %}
>
>     Some content.
>     {%- endif %}
>     ```
>
>     If the condition is true, there will be exactly one blank line
>     between "Some text" and "Some content". If not, there won't be
>     extreanous trailing blank lines :+1:
>
> - **To collapse content down**, eat spaces on the **right**, and add new lines
>     at the **bottom** of the Jinja block:
>
>     ```django
>     {% if some_condition -%}
>     Some content.
>
>     {% endif -%}
>     Some text.
>     ```
>
>     If the condition is true, there will be exactly one blank line
>     between "Some content" and "Some text". If not, there won't be
>     extreanous leading blank lines :+1:

### Extra Jinja context

[(--jinja-context)](cli.md#jinja_context)

Your custom changelog templates can support user-provided extra Jinja context.
This extra context is available in the `jinja_context` variable, which is a dictionary,
and is passed by users with the `-j`, `--jinja-context` CLI option
or with the `jinja_context` configuration option.

For example, you could let users specify their own changelog footer
by adding this at the end of your template:

```django
{% if jinja_context.footer %}
{{ jinja_context.footer }}
{% endif %}
```

Then users would be able to provide their own footer with the CLI option:

```bash
git-changelog -t path:changelog.md -j footer="Copyright 2024 My Company"
```

...or with the configuration option:

```toml
template = "path:changelog.md"

[jinja_context]
footer = "Copyright 2024 My Company"
```

## Filter commits

[(--filter-commits)](cli.md#filter_commits)

Sometimes it may be useful to use a limited set of commits, for example, if your
project has migrated to SemVer recently and you want to ignore old non-conventional commits.

This is possible through the option `-F`, `--filter-commits`, which takes a
*revision-range* to select the commits that will be used in the changelog.
This option will pass the [revision-range](https://git-scm.com/docs/git-log#
Documentation/git-log.txt-ltrevision-rangegt) to `git log`, so it will follow
the rules defined by Git.

For example, to use commits from tag `0.5.0` up to latest:

```bash
git-changelog --filter-commits "0.5.0.."
```

Or using the commit hash:

```bash
git-changelog --filter-commits "2c0dbb8.."
```

## Understand the relationship with SemVer

[(--bump)](cli.md#bump)<br>
[(--versioning)](cli.md#versioning)<br>
[(--zerover)](cli.md#zerover)

*Although git-changelog supports several [versioning schemes](#choose-a-versioning-scheme),
SemVer plays a particular role when managing versions.*

[SemVer][semver], or Semantic Versioning, helps users of tools and libraries
understand the impact of version changes. To quote SemVer itself:

> Given a version number MAJOR.MINOR.PATCH, increment the:
>
> 1. MAJOR version when you make incompatible API changes
> 2. MINOR version when you add functionality in a backwards compatible manner
> 3. PATCH version when you make backwards compatible bug fixes

Thanks to the SemVer specification and the commit message conventions,
*git-changelog* is able to guess the new version your project is supposed
to take given a set of untagged commits (commits more recent than the latest tag).
An "Added" (basic convention) or "feat" (Angular/Karma/ConventionalCommit) commit
will bump the MINOR part of the latest tag. Other types will bump the PATCH part.
Commits containing breaking changes will bump the MAJOR part, unless MAJOR is 0,
in which case they'll only bump the MINOR part.

To tell *git-changelog* to try and guess the new version, use the `--bump=auto` CLI option:

```bash
git-changelog --bump auto
```

You can also specify a version to bump to directly:

```bash
git-changelog --bump 2.3.1
```

Or which part of the version to bump, resetting
numbers on its right to 0:

```bash
git-changelog --bump major  # 1.2.3 -> 2.0.0
git-changelog --bump minor  # 1.2.3 -> 1.3.0
git-changelog --bump patch  # 1.2.3 -> 1.2.4
```

As different schemes have different bumping strategies,
the selected scheme will affect the `--bump` option.
See [PEP 440 strategies](#pep-440) and [SemVer strategies](#semver).

### ZeroVer

Note that by default, "ZeroVer" mode is activated,
which means that a breaking change will only bump the major version
if the major version is already at `1` or more,
otherwise it will bump the minor version.

While this behavior is described in SemVer's specification,
the "ZeroVer" name comes from the satyrical
[ZeroVer (or zer0ver, 0ver) versioning scheme](https://0ver.org/).

When you are ready to bump to 1.0.0,
just pass this version as value, or use the `-Z`, `--no-zerover` flag.

Let say we are at version `0.1.0`, and unreleased commits
contain breaking changes:

```bash
git-changelog --bump auto      # 0.2.0
git-changelog --bump auto -Z   # 1.0.0
git-changelog --bump major     # 0.2.0
git-changelog --bump major -Z  # 1.0.0
```

If we are already at version `1.0.0`, and unreleased commits
contain breaking changes again:

```bash
git-changelog --bump auto      # 2.0.0
git-changelog --bump auto -Z   # 2.0.0, same
git-changelog --bump major     # 2.0.0
git-changelog --bump major -Z  # 2.0.0, same
```

If you use *git-changelog* in CI, to update your changelog automatically,
it is recommended to use a configuration file instead of the CLI option.
On a fresh project, start by setting `zerover = true` in one of the supported
[configuration files](#configuration-files). Then, once you are ready
to bump to v1, set `zerover = false` and commit it as a breaking change.
Once v1 is released, the setting has no use anymore, and you can remove it
from your configuration file.

## Choose a versioning scheme

[(--bump)](cli.md#bump)<br>
[(--versioning)](cli.md#versioning)<br>
[(--zerover)](cli.md#zerover)

*git-changelog* currently supports the following versioning schemes:

- `pep440`, see [PEP 440][pep440]
- `semver`, see [SemVer][semver]

Versioning schemes are useful to *git-changelog* when grouping commits
from your Git history into versions, and when bumping versions.

To choose a specific scheme, use the `-n`, `--versioning` CLI option:

```bash
git-changelog -n pep440
```

For backward compatibility reasons, it uses the SemVer scheme by default.

As different schemes have different bumping strategies,
the selected scheme will affect the `--bump` option.

### PEP 440

The bumping strategies supported by the PEP 440 scheme
are described in the table below.
Bumping a specific part of the version will remove or reset the parts
on its right to 0.

Strategy              | Example               | Description
--------------------- | --------------------- | -----------
`auto`                | -                     | Guess which of major, minor or micro to bump<br>thanks to the Git history and commit message conventions.
`epoch`               | `1!1` → `2!1`         | Bump [epoch][pep440-epoch], keeping [final release][pep440-release] only.
`release`             | `1rc2` → `1`          | Bump version to a [final release][pep440-release].
`major`               | `1.1` → `2.0`         | Bump major version.
`minor`               | `1.1.1` → `1.2.0`     | Bump minor version.
`micro` (or `patch`)  | `1.1.1.1` → `1.1.2.0` | Bump micro version.
`pre`                 | `1a0` → `1a1`         | Bump current [pre-release][pep440-pre] (alpha `a`, beta `b` or release candidate `rc`).
`alpha`               | `1a0` → `1a1`         | Bump current alpha pre-release.
`beta`                | `1b0` → `1b1`         | Bump current beta pre-release.
`candidate`           | `1rc0` → `1rc1`       | Bump current candidate pre-release.
`post`                | `1` → `1.post0`       | Bump to a [post-release][pep440-post].
`dev`                 | `1.dev0` → `1.dev1`   | Bump current [dev-release][pep440-dev].
`auto+alpha`          | -                     | Guess major/minor/micro bump, and set it to alpha pre-release.
`auto+beta`           | -                     | Guess major/minor/micro bump, and set it to beta pre-release.
`auto+candidate`      | -                     | Guess major/minor/micro bump, and set it to candidate pre-release.
`auto+dev`            | -                     | Guess major/minor/micro bump, and set it to dev-release.
`auto+alpha+dev`      | -                     | Guess major/minor/micro bump, and set it to alpha pre-release and dev-release.
`auto+beta+dev`       | -                     | Guess major/minor/micro bump, and set it to beta pre-release and dev-release.
`auto+candidate+dev`  | -                     | Guess major/minor/micro bump, and set it to candidate pre-release and dev-release.
`major+alpha`         | `1` → `2a0`           | Bump major version and set it to alpha pre-release.
`major+beta`          | `1` → `2b0`           | Bump major version and set it to beta pre-release.
`major+candidate`     | `1` → `2rc0`          | Bump major version and set it to candidate pre-release.
`major+dev`           | `1` → `2.dev0`        | Bump major version and set it to dev-release.
`major+alpha+dev`     | `1` → `2a0.dev0`      | Bump major version and set it to alpha pre-release and dev-release.
`major+beta+dev`      | `1` → `2b0.dev0`      | Bump major version and set it to beta pre-release and dev-release.
`major+candidate+dev` | `1` → `2rc0.dev0`     | Bump major version and set it to candidate pre-release and dev-release.
`minor+alpha`         | `1` → `1.1a0`         | Bump minor version and set it to alpha pre-release.
`minor+beta`          | `1` → `1.1b0`         | Bump minor version and set it to beta pre-release.
`minor+candidate`     | `1` → `1.1rc0`        | Bump minor version and set it to candidate pre-release.
`minor+dev`           | `1` → `1.1.dev0`      | Bump minor version and set it to dev-release.
`minor+alpha+dev`     | `1` → `1.1a0.dev0`    | Bump minor version and set it to alpha pre-release and dev-release.
`minor+beta+dev`      | `1` → `1.1b0.dev0`    | Bump minor version and set it to beta pre-release and dev-release.
`minor+candidate+dev` | `1` → `1.1rc0.dev0`   | Bump minor version and set it to candidate pre-release and dev-release.
`micro+alpha`         | `1` → `1.0.1a0`       | Bump micro version and set it to alpha pre-release.
`micro+beta`          | `1` → `1.0.1b0`       | Bump micro version and set it to beta pre-release.
`micro+candidate`     | `1` → `1.0.1rc0`      | Bump micro version and set it to candidate pre-release.
`micro+dev`           | `1` → `1.0.1.dev0`    | Bump micro version and set it to dev-release.
`micro+alpha+dev`     | `1` → `1.0.1a0.dev0`  | Bump micro version and set it to alpha pre-release and dev-release.
`micro+beta+dev`      | `1` → `1.0.1b0.dev0`  | Bump micro version and set it to beta pre-release and dev-release.
`micro+candidate+dev` | `1` → `1.0.1rc0.dev0` | Bump micro version and set it to candidate pre-release and dev-release.
`alpha+dev`           | `1a0` → `1a1.dev0`    | Bump current alpha pre-release and set it to a dev-release.
`beta+dev`            | `1b0` → `1b1.dev0`    | Bump current beta pre-release and set it to a dev-release.
`candidate+dev`       | `1rc0` → `1rc1.dev0`  | Bump current candidate pre-release and set it to a dev-release.

Try it out:

```pyodide install="git-changelog"
from git_changelog.versioning import bump_pep440

# "auto" strategies are not directly supported by this function
print(bump_pep440("1.2.3", "minor+alpha"))
```

The `v` prefix will be preserved when bumping a version: `v1` -> `v2`.

The bumping strategies for PEP 440 try to make the most sense,
allowing you to bump in a semantic way and preventing version downgrade mistakes.
Specifically, it is not possible:

- to bump from a final release version to a pre-release or a dev-release version
- to bump from a pre-release version to a lower pre-release version or a dev-version
- more generally, to bump from any version to any lower version

If you need to "bump" to a version that is lower than the latest released one,
you must explicitely pass the version to the `--bump` option:

```bash
# latest release is 1.1
git-changelog --bump 1.0
```

### SemVer

The bumping strategies supported by the SemVer scheme
are described in the table below.
Bumping a specific part of the version will remove or reset the parts
on its right to 0.

Strategy              | Example               | Description
--------------------- | --------------------- | -----------
`auto`                | -                     | Guess which of major, minor or patch to bump<br>thanks to the Git history and commit message conventions.
`major`               | `1.1.1` → `2.0.0`     | Bump major version.
`minor`               | `1.1.1` → `1.2.0`     | Bump minor version.
`patch`               | `1.1.1` → `1.1.2`     | Bump micro version.
`release`             | `1.1.1-a2` → `1.1.1`  | Bump version to a final release (remove pre-release and build metadata).

Try it out:

```pyodide install="git-changelog"
from git_changelog.versioning import bump_semver

# the "auto" strategy is not directly supported by this function
print(bump_semver("1.2.3", "minor"))
```

The `v` prefix will be preserved when bumping a version: `v1.0.0` -> `v2.0.0`.

The bumping strategies for SemVer will prevent you from bumping from any version to a lower one.
It does not support bump pre-release metadata or build metadata
because these are not standardized.

If you need to "bump" to a version that is lower than the latest released one,
or to add pre-release or build metadata,
you must explicitely pass the version to the `--bump` option:

```bash
# downgrade
git-changelog --bump 1.1.0

# add pre-release metadata
git-changelog --bump 2.0.0-alpha1
```

## Show bumped version

To retrieve the bumped version (for example, to pass the same version to your package builder) use the `--bumped-version` flag. This flag forces output to stdout (overriding `--output`) and sets `--bump` to `auto` if it isn’t already set.

```bash
git-changelog --bumped-version
# prints the next auto-bumped version, e.g. 1.2.3

git-changelog --bump major --bumped-version
# prints the next major version, e.g. 2.0.0
```

## Parse additional information in commit messages

*git-changelog* is able to parse the body of commit messages
to find additional information.

### Provider-specific references

[(--parse-refs)](cli.md#parse_refs)<br>
[(--provider)](cli.md#provider)

*git-changelog* will detect when you are using GitHub, GitLab or Bitbucket
by checking the `origin` remote configured in your local clone
(or the remote indicated by the value of the `GIT_CHANGELOG_REMOTE` environment variable).

Detecting the provider allows *git-changelog* to build URLs to specific commits and tags.
But it also allows it to parse text references understood by these providers
in the commit messages. For example: #18 (issue) or a78bcf2e (commit hash).
These references are then available when rendering the changelog template,
allowing to add links to issues, pull requests, users, etc.

Example of a commit message with GitLab references:

```text
fix: Fix atrocious bug

Fixes issue #14.
Follow-up of MR !7.
Part of milestone %2.
```

To enable provider-specific reference parsing, use the `-r` or `--parse-refs` CLI option:

```bash
git-changelog --parse-refs
```

Provider-references are a bit limited, difficult to parse and favor vendor lock-in,
so for these reasons we do not recommend them. Instead, we recommend using Git trailers.

### Git trailers

[(--trailers)](cli.md#parse_trailers)

Git has an [`interpret-trailers`][git-trailers] command
that allows to add or parse trailers line to commit messages.
Trailers line are located in the footer of commit message:
there must be a blank line between the body and the first trailer.
Each trailer is a line of the form `token: value`, for example
`Co-authored-by: Timothée Mazzucotelli <pawamoy@pm.me>`.

The tokens are specified not to allow whitespace in them,
but *git-changelog* takes the liberty to lift up this limitation
for convenience. It means you can write `Issue 18: https://...`
instead of `Issue-18: https://...`. The first colon + space (`: `)
delimitate the token and value.

Example of a commit message with Git trailers:

```text
fix: Fix atrocious bug

Fixes issue #14: https://github.com/super/repo/issues/14
Follow-up of PR #7: https://github.com/super/repo/pull/7
Part of epic #5: https://agile-software.com/super/project/epics/5
```

As you can see, compared to provider-specific references,
trailers are written out explicitly, so it's a bit more work,
but this ensures your changelog can be rendered correctly *anywhere*,
not just on GitHub, GitLab or Bitbucket, and without pre/post-processing.

Trailers are rendered in the Keep A Changelog template.
If the value is an URL, a link is created with the token as title.
If not, the trailer is written as is.

Example of how the previous trailers are rendered:

```md exec="1" source="material-block"
- Fix atrocious bug ([aafa779](https://github.com/super/repo/commit/aafa7793ec02a) by John Doe).
    [Fixes issue #14](https://github.com/super/repo/issues/14),
    [Follow-up of PR #7](https://github.com/super/repo/pull/7),
    [Part of epic #5](https://agile-software.com/super/project/epics/5)
```

To enable Git trailers parsing, use the `-T` or `--trailers` CLI option:

```bash
git-changelog --trailers
```

## Update changelog in place

[(--in-place)](cli.md#in_place)<br>
[(--marker-line)](cli.md#marker_line)<br>
[(--version-regex)](cli.md#version_regex)

Writing the whole generated changelog to a file is nice,
but sometimes you need to tweak the entries in your changelog
and you don't want to overwrite these slight modifications
each time your regenerate your changelog.

For this reason, *git-changelog* is able to update a changelog file in-place.
It means that it will only insert new entries at the top of the changelog,
without modifying existing ones.

To update a changelog in-place, use the `-i` or `--in-place` CLI option:

```bash
git-changelog --output CHANGELOG.md --in-place
```

To achieve this, *git-changelog* searches for versions (entries)
already written to the changelog with a regular expression.
The verions that are not found in the changelog will be added at the top.
To know where to add them exactly, we search for a marker line in the changelog.
This marker line is an HTML comment: it is not visible when the changelog
is displayed in web pages.

To support in-place updates in a custom template, you have two choices:

1. format versions in your template so they match the default regular expression,
    and use the default marker line(s) to tell *git-changelog* where
    to insert new entries. Here are these default values:

    ```python
    DEFAULT_VERSION_REGEX = r"^## \[(?P<version>v?[^\]]+)"
    DEFAULT_MARKER_LINE = "<!-- insertion marker -->"
    ```

2. provide a custom regular expression and marker line,
    to match the contents of your custom template,
    with the `-g` or `--version-regex`, and `-m` or `--marker-line` CLI options:

    ```bash
    git-changelog --output CHANGELOG.md --in-place \
        --version-regex '<a href="[^"]+">(?P<version>[^<]+)' \
        --marker-line '<!-- new entries will be injected here -->'
    ```

When only one marker line is found in the template,
new entries are inserted at this line exactly, overwriting it
(but the marker is added again by the new entries themselves).

When two marker lines are found, new entries are applied between
those two lines, overwriting the previous contents.
This is useful when you don't tell *git-changelog* to bump the latest version:
you will have an "Unreleased" section that is overwritten and updated
each time you update your changelog in-place.

## Output release notes

[(--input)](cli.md#input)<br>
[(--release-notes)](cli.md#release_notes)

Some platforms allow to announce releases with additional "release notes".
*git-changelog* can help generating release notes too, by simply
reading your existing changelog and printing the latest entry.
So if you just pushed a tag with an updated changelog,
you can use *git-changelog* in Continuous Integration/Deployment
to create a release (specific to your platform, e.g. GitHub)
with the latest changelog entry as release notes.

For example, on GitHub, with the [softprops/action-gh-release][] action:

```yaml
name: github_release

on: push

jobs:
  github_release:
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/')
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Setup Python
      uses: actions/setup-python@v4
    - name: Install git-changelog
      run: pip install git-changelog
    - name: Prepare release notes
      run: git-changelog --release-notes > release-notes.md
    - name: Create GitHub release
      uses: softprops/action-gh-release@v1
      with:
        body_path: release-notes.md
```

By default *git-changelog* will try to read release notes
from a file named `CHANGELOG.md`. Use the `-i`, `--input`
option to specify another file to read from.
Other options can be used to help *git-changelog* retrieving
the latest entry from your changelog: `--version-regex`
and `--marker-line`.

[keepachangelog]: https://keepachangelog.com/en/1.0.0/
[conventional-commit]: https://www.conventionalcommits.org/en/v1.0.0-beta.4/
[jinja]: https://jinja.palletsprojects.com/en/3.1.x/
[semver]: https://semver.org/
[git-trailers]: https://git-scm.com/docs/git-interpret-trailers
[softprops/action-gh-release]: https://github.com/softprops/action-gh-release
[keepachangelog-template]: https://github.com/pawamoy/git-changelog/tree/main/src/git_changelog/templates/keepachangelog.md.jinja
[builtin-templates]: https://github.com/pawamoy/git-changelog/tree/main/src/git_changelog/templates
[control-whitespace]: https://jinja.palletsprojects.com/en/3.1.x/templates/#whitespace-control
[pep440]: https://peps.python.org/pep-0440/
[pep440-epoch]: https://peps.python.org/pep-0440/#version-epochs
[pep440-pre]: https://peps.python.org/pep-0440/#pre-releases
[pep440-post]: https://peps.python.org/pep-0440/#post-releases
[pep440-dev]: https://peps.python.org/pep-0440/#developmental-releases
[pep440-release]: https://peps.python.org/pep-0440/#final-releases