diff --git a/.github/fixtures/test-invert-ignore-tags/cliff.toml b/.github/fixtures/test-invert-ignore-tags/cliff.toml new file mode 100644 index 0000000000..bc7fee5670 --- /dev/null +++ b/.github/fixtures/test-invert-ignore-tags/cliff.toml @@ -0,0 +1,34 @@ +[changelog] +# changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\ + {% endfor %} +{% endfor %}\n +""" +# template for the changelog footer +footer = """ + +""" +# remove the leading and trailing whitespace from the templates +trim = true + +[git] +# regex for skipping tags +skip_tags = "v0.1.0-beta.1" +# regex for ignoring tags +ignore_tags = "v.*-beta.*" +count_tags = "v0.2.0" diff --git a/.github/fixtures/test-invert-ignore-tags/commit.sh b/.github/fixtures/test-invert-ignore-tags/commit.sh new file mode 100755 index 0000000000..fa448ec4ea --- /dev/null +++ b/.github/fixtures/test-invert-ignore-tags/commit.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -e + +GIT_COMMITTER_DATE="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add skip feature" +git tag v0.1.0-beta.1 + +GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "feat: add feature 1" +GIT_COMMITTER_DATE="2021-01-23 01:23:47" git commit --allow-empty -m "feat: fix feature 1" +git tag v0.1.0 + +GIT_COMMITTER_DATE="2021-01-23 01:23:48" git commit --allow-empty -m "feat: add feature 2" +git tag v0.2.0-beta.1 + +GIT_COMMITTER_DATE="2021-01-23 01:23:49" git commit --allow-empty -m "feat: add feature 3" +git tag v0.2.0 diff --git a/.github/fixtures/test-invert-ignore-tags/expected.md b/.github/fixtures/test-invert-ignore-tags/expected.md new file mode 100644 index 0000000000..0b152c22d2 --- /dev/null +++ b/.github/fixtures/test-invert-ignore-tags/expected.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [0.2.0] - 2021-01-23 + +### Feat + +- Add feature 1 +- Fix feature 1 +- Add feature 2 +- Add feature 3 + + diff --git a/.github/workflows/test-fixtures.yml b/.github/workflows/test-fixtures.yml index f732dc1e3d..ba9daa2f4a 100644 --- a/.github/workflows/test-fixtures.yml +++ b/.github/workflows/test-fixtures.yml @@ -22,6 +22,7 @@ jobs: - fixtures-name: test-gitea-integration - fixtures-name: test-bitbucket-integration - fixtures-name: test-ignore-tags + - fixtures-name: test-invert-ignore-tags - fixtures-name: test-topo-order command: --latest - fixtures-name: test-date-order diff --git a/git-cliff-core/src/changelog.rs b/git-cliff-core/src/changelog.rs index 9af571aa08..2961872438 100644 --- a/git-cliff-core/src/changelog.rs +++ b/git-cliff-core/src/changelog.rs @@ -784,6 +784,7 @@ mod test { tag_pattern: None, skip_tags: Regex::new("v3.*").ok(), ignore_tags: None, + count_tags: None, topo_order: Some(false), sort_commits: Some(String::from("oldest")), link_parsers: None, diff --git a/git-cliff-core/src/config.rs b/git-cliff-core/src/config.rs index a0454661a3..4c9d423bbf 100644 --- a/git-cliff-core/src/config.rs +++ b/git-cliff-core/src/config.rs @@ -109,6 +109,9 @@ pub struct GitConfig { /// Regex to ignore matched tags. #[serde(with = "serde_regex", default)] pub ignore_tags: Option, + /// Regex to count matched tags. + #[serde(with = "serde_regex", default)] + pub count_tags: Option, /// Whether to sort tags topologically. pub topo_order: Option, /// Sorting of the commits inside sections. diff --git a/git-cliff-core/tests/integration_test.rs b/git-cliff-core/tests/integration_test.rs index 47f2791d06..355dd11526 100644 --- a/git-cliff-core/tests/integration_test.rs +++ b/git-cliff-core/tests/integration_test.rs @@ -118,6 +118,7 @@ fn generate_changelog() -> Result<()> { tag_pattern: None, skip_tags: None, ignore_tags: None, + count_tags: None, topo_order: None, sort_commits: None, link_parsers: Some(vec![ diff --git a/git-cliff/src/args.rs b/git-cliff/src/args.rs index f0decb7944..444af6d3e8 100644 --- a/git-cliff/src/args.rs +++ b/git-cliff/src/args.rs @@ -154,6 +154,9 @@ pub struct Opt { /// Sets the tags to ignore in the changelog. #[arg(long, env = "GIT_CLIFF_IGNORE_TAGS", value_name = "PATTERN")] pub ignore_tags: Option, + /// Sets the tags to count in the changelog. + #[arg(long, env = "GIT_CLIFF_COUNT_TAGS", value_name = "PATTERN")] + pub count_tags: Option, /// Sets commits that will be skipped in the changelog. #[arg( long, diff --git a/git-cliff/src/lib.rs b/git-cliff/src/lib.rs index ec908883f8..ed88cce637 100644 --- a/git-cliff/src/lib.rs +++ b/git-cliff/src/lib.rs @@ -86,6 +86,7 @@ fn process_repository<'a>( let mut tags = repository.tags(&config.git.tag_pattern, args.topo_order)?; let skip_regex = config.git.skip_tags.as_ref(); let ignore_regex = config.git.ignore_tags.as_ref(); + let count_tags = config.git.count_tags.as_ref(); tags.retain(|_, tag| { let name = &tag.name; @@ -95,6 +96,14 @@ fn process_repository<'a>( return true; } + let count = count_tags.map_or(true, |r| { + let count_tag = r.is_match(name); + if count_tag { + trace!("Counting release: {}", name) + } + count_tag + }); + let ignore = ignore_regex.is_some_and(|r| { if r.as_str().trim().is_empty() { return false; @@ -106,7 +115,8 @@ fn process_repository<'a>( } ignore_tag }); - !ignore + + count && !ignore }); if !config.remote.github.is_set() { @@ -508,6 +518,9 @@ pub fn run(mut args: Opt) -> Result<()> { if args.ignore_tags.is_some() { config.git.ignore_tags.clone_from(&args.ignore_tags); } + if args.count_tags.is_some() { + config.git.count_tags.clone_from(&args.count_tags); + } // Process the repositories. let repositories = args.repository.clone().unwrap_or(vec![env::current_dir()?]); let mut releases = Vec::::new(); diff --git a/website/docs/configuration/git.md b/website/docs/configuration/git.md index 3c3722c490..8002c760e8 100644 --- a/website/docs/configuration/git.md +++ b/website/docs/configuration/git.md @@ -200,12 +200,28 @@ A regex for skip processing the matched tags. A regex for ignore processing the matched tags. +While `skip_tags` drop commits from the changelog, `ignore_tags` include ignored commits into the next tag. + +:::note + +Note that if a commit has multiple tags, any matched tag will result in all associated tags being ignored, including those not explicitly matched by the regex. This is because git-cliff processes tags at the commit level rather than individually. +For more details, you can view the discussion [here](https://github.com/orhun/git-cliff/discussions/707). + +::: + This value can be also overridden with using the `--ignore-tags` argument. -While `skip_tags` drop commits from the changelog, `ignore_tags` include ignored commits into the next tag. +### count_tags + +A regex for _counting in_ the matched tags in the final result. + +:::info + +`count_tags` work like an inverted version of `ignore_tags`, that include all the commits but only count the specific tags. + +::: -* Note that if a commit has multiple tags, any matched tag will result in all associated tags being ignored, including those not explicitly matched by the regex. This is because git-cliff processes tags at the commit level rather than individually. -For more details, you can view the discussion [here](https://github.com/orhun/git-cliff/discussions/707) +This value can be also overridden with using the `--count-tags` argument. ### topo_order diff --git a/website/docs/usage/args.md b/website/docs/usage/args.md index c4926f325e..9c500952a7 100644 --- a/website/docs/usage/args.md +++ b/website/docs/usage/args.md @@ -37,6 +37,7 @@ git-cliff [FLAGS] [OPTIONS] [--] [RANGE] --with-commit ... Sets custom commit messages to include in the changelog [env: GIT_CLIFF_WITH_COMMIT=] --with-tag-message [] Sets custom message for the latest release [env: GIT_CLIFF_WITH_TAG_MESSAGE=] --ignore-tags Sets the tags to ignore in the changelog [env: GIT_CLIFF_IGNORE_TAGS=] + --count-tags Sets the tags to count in the changelog [env: GIT_CLIFF_COUNT_TAGS=] --skip-commit ... Sets commits that will be skipped in the changelog [env: GIT_CLIFF_SKIP_COMMIT=] -p, --prepend Prepends entries to the given changelog file [env: GIT_CLIFF_PREPEND=] -o, --output [] Writes output to the given file [env: GIT_CLIFF_OUTPUT=]