Quick start#

This walks through a first config file and a first bump. It assumes bumpversion is installed and that you are in a Git repository.

1. Write a config file#

Create .bumpversion.toml at the repository root. It needs the current version and the list of files that mention it:

.bumpversion.toml
[tool.bumpversion]
current_version = "1.4.2"
commit = true
tag = true

[[tool.bumpversion.files]]
filename = "Cargo.toml"

[[tool.bumpversion.files]]
filename = "README.md"

That is the whole configuration for a project whose version appears in Cargo.toml and in the README:

Cargo.toml
[package]
name = "widget"
version = "1.4.2"
edition = "2024"
README.md
# widget 1.4.2

Install with `cargo add widget@1.4.2`.

You do not list .bumpversion.toml itself — its current_version is always updated as part of the bump.

2. See what the next version would be#

bumpversion show-bump patch

show-bump computes the next version and prints it. It writes nothing and touches no files:

$ bumpversion show-bump patch
 
old_version=1.4.2
new_version=1.4.3
 
$ bumpversion show-bump minor
 
old_version=1.4.2
new_version=1.5.0
 
$ bumpversion show-bump major
 
old_version=1.4.2
new_version=2.0.0

Note what major does: minor and patch both reset to zero. Every component below the one you bump resets, which is what makes 1.4.2 become 2.0.0 rather than 2.4.2.

3. Preview the whole bump#

bumpversion --dry-run --verbose patch

This is the command worth building a habit around. --dry-run gates every write, and --verbose prints the report — so you see the exact diff of every file, the commit that would be made, and the tag that would be created, before anything happens:

$ bumpversion --dry-run -vv bump patch
 
 [DRY-RUN] [current version]
 [DRY-RUN] 	1.4.2
 [DRY-RUN] 	major=1  minor=4  patch=2
 [DRY-RUN] [setup]
 [DRY-RUN] 	no setup hooks defined
 [DRY-RUN] [new version]
 [DRY-RUN] 	1.4.3
 [DRY-RUN] 	major=1  minor=4  patch=3
 [DRY-RUN] 
 [DRY-RUN] [./Cargo.toml]
 [DRY-RUN] 	replacing `{current_version}` (1.4.2) with `{new_version}` (1.4.3)
 [DRY-RUN] 
 [DRY-RUN] 	Differences (-before|+after):
 [DRY-RUN] 	 [package]
 [DRY-RUN] 	 name = "widget"
 [DRY-RUN] 	-version = "1.4.2"
 [DRY-RUN] 	+version = "1.4.3"
 [DRY-RUN] 	 edition = "2024"
 [DRY-RUN] 
 [DRY-RUN] [./README.md]
 [DRY-RUN] 	replacing `{current_version}` (1.4.2) with `{new_version}` (1.4.3)
 [DRY-RUN] 
 [DRY-RUN] 	Differences (-before|+after):
 [DRY-RUN] 	-# widget 1.4.2
 [DRY-RUN] 	+# widget 1.4.3
 [DRY-RUN] 
 [DRY-RUN] 	-Install with `cargo add widget@1.4.2`.
 [DRY-RUN] 	+Install with `cargo add widget@1.4.3`.
 [DRY-RUN] 
 [DRY-RUN] [./.bumpversion.toml]
 [DRY-RUN] 	replacing `{current_version}` (1.4.2) with `{new_version}` (1.4.3)
 [DRY-RUN] 
 [DRY-RUN] 	Differences (-before|+after):
 [DRY-RUN] 	 [tool.bumpversion]
 [DRY-RUN] 	-current_version = "1.4.2"
 [DRY-RUN] 	+current_version = "1.4.3"
 [DRY-RUN] 	 commit = true
 [DRY-RUN] 	 tag = true
 [DRY-RUN] 
 [DRY-RUN] 	 [[tool.bumpversion.files]]
 [DRY-RUN] [pre-commit]
 [DRY-RUN] 	no pre-commit hooks defined
 [DRY-RUN] [commit]
 [DRY-RUN] 	   add ./Cargo.toml
 [DRY-RUN] 	   add ./README.md
 [DRY-RUN] 	   add ./.bumpversion.toml
 [DRY-RUN] 	commit Bump version: 1.4.2 → 1.4.3
 [DRY-RUN] [tag]
 [DRY-RUN] 	tag = v1.4.3
 [DRY-RUN] 	message = Bump version: 1.4.2 → 1.4.3
 [DRY-RUN] 	sign = false
 [DRY-RUN] [post-commit]
 [DRY-RUN] 	no post-commit hooks defined

Read it top to bottom:

  • [current version] and [new version] — the version before and after. The second line under each (shown here because the run used -vv) breaks the version into its components.
  • One block per file — the resolved search and replace templates, then a unified diff of the change. Note that .bumpversion.toml appears even though it is not in [[files]].
  • [commit] — every file that would be staged, and the commit message.
  • [tag] — the tag name, its message, and whether it would be signed.
  • [setup], [pre-commit], [post-commit] — the hooks, or a note that none are configured.

The [DRY-RUN] prefix on every line is exactly that: it appears only because this was a dry run.

Without --verbose, a successful bump prints nothing at all. That is the default, and it surprises most people the first time. See Verbosity.

4. Do it#

bumpversion patch

The files are rewritten. Because the example config sets commit = true and tag = true, the changes are also committed and tagged as v1.4.3. Both default to false — see Commits and tags.

bumpversion refuses to run on a dirty working tree, so the release commit contains only the version bump. Pass --allow-dirty when you mean to include other staged work.

5. Read values back#

show prints resolved configuration and repository state — useful in scripts and for working out why a template rendered the way it did:

$ bumpversion show current_version
 
1.4.2
 
$ bumpversion show current_version current_tag branch_name
 
current_version=1.4.2
current_tag=v1.4.2
branch_name=main

One variable prints a bare value; two or more print name=value lines, so the output is easy to consume from a shell.

Where to go next#

  • The version scheme is 1.4.2 only because that is the default. A pre-release ladder or a date-stamped scheme is a parse regex and a couple of serialize patterns — see Version scheme.
  • Rewriting the same string across many packages is one glob entry — see Files to rewrite.
  • If your project already has a pyproject.toml or a setup.cfg with a bumpversion section, you do not need .bumpversion.toml at all — see Config file formats.