Repository: orhun/git-cliff (language: python)

Issue:
Regenerating changelog after taging changes the date
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Description of the bug

I've been using `git cliff -t vX.Y.Z` as part of a build system as a way to lint the release and make sure everything got generated properly. This works fine the day-of, but fails if run later. The generated changelog always has the *current* date even if the tag and release already exists.

I understand there is a cart-before-the-horse issue at play here, but it seems like if a tag exists, the release date should be derived from the tag rather than the current time. Notably this is only a problem for the *current* release, it does not affect the backlog of generated releases all the rest of which are untouched.

### Steps To Reproduce

Rebuild a changelog while on a tagged release on a day later than the changelog was originally generated.

### Expected behavior

Release date to be derived from the tag if extant, current date if not.

### Screenshots / Logs

_No response_

### Software information

git-cliff 2.4.0

### Additional context

_No response_


Discussion / hints:

Fix patch:
diff --git a/git-cliff/src/lib.rs b/git-cliff/src/lib.rs
index 85d4e8215a..c71007dfa2 100644
--- a/git-cliff/src/lib.rs
+++ b/git-cliff/src/lib.rs
@@ -235,11 +235,13 @@ fn process_repository<'a>(
 	}
 
 	// Update tags.
+	let mut tag_timestamp = None;
 	if let Some(ref tag) = args.tag {
 		if let Some(commit_id) = commits.first().map(|c| c.id().to_string()) {
 			match tags.get(&commit_id) {
 				Some(tag) => {
 					warn!("There is already a tag ({}) for {}", tag.name, commit_id);
+					tag_timestamp = Some(commits[0].time().seconds());
 				}
 				None => {
 					tags.insert(commit_id, repository.resolve_tag(tag));
@@ -263,10 +265,13 @@ fn process_repository<'a>(
 			release.message = tag.message.clone();
 			release.commit_id = Some(commit_id);
 			release.timestamp = if args.tag.as_deref() == Some(tag.name.as_str()) {
-				SystemTime::now()
-					.duration_since(UNIX_EPOCH)?
-					.as_secs()
-					.try_into()?
+				match tag_timestamp {
+					Some(timestamp) => timestamp,
+					None => SystemTime::now()
+						.duration_since(UNIX_EPOCH)?
+						.as_secs()
+						.try_into()?,
+				}
 			} else {
 				git_commit.time().seconds()
 			};


Test patch:
diff --git a/.github/fixtures/test-unchanged-tag-date/cliff.toml b/.github/fixtures/test-unchanged-tag-date/cliff.toml
new file mode 100644
index 0000000000..b26308cde6
--- /dev/null
+++ b/.github/fixtures/test-unchanged-tag-date/cliff.toml
@@ -0,0 +1,34 @@
+[changelog]
+# template for the changelog footer
+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 %}
+        - {{ commit.message | upper_first }}\
+    {% endfor %}
+{% endfor %}\n
+"""
+# template for the changelog footer
+footer = """
+<!-- generated by git-cliff -->
+"""
+# remove the leading and trailing whitespace from the templates
+trim = true
+
+[git]
+# regex for parsing and grouping commits
+commit_parsers = [
+    { message = "^feat", group = "Features", default_scope = "app" },
+    { message = "^fix", group = "Bug Fixes", scope = "cli" },
+]
diff --git a/.github/fixtures/test-unchanged-tag-date/commit.sh b/.github/fixtures/test-unchanged-tag-date/commit.sh
new file mode 100755
index 0000000000..9a42410d96
--- /dev/null
+++ b/.github/fixtures/test-unchanged-tag-date/commit.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+set -e
+
+GIT_COMMITTER_DATE="2022-04-06 01:25:08" git commit --allow-empty -m "Initial commit"
+GIT_COMMITTER_DATE="2022-04-06 01:25:09" git commit --allow-empty -m "feat: add feature 1"
+GIT_COMMITTER_DATE="2022-04-06 01:25:10" git commit --allow-empty -m "fix: fix feature 1"
+git tag v0.1.0
+GIT_COMMITTER_DATE="2022-04-06 01:25:11" git commit --allow-empty -m "feat(gui): add feature 2"
+GIT_COMMITTER_DATE="2022-04-06 01:25:12" git commit --allow-empty -m "fix(gui): fix feature 2"
+git tag v0.2.0
diff --git a/.github/fixtures/test-unchanged-tag-date/expected.md b/.github/fixtures/test-unchanged-tag-date/expected.md
new file mode 100644
index 0000000000..9fb4d735f7
--- /dev/null
+++ b/.github/fixtures/test-unchanged-tag-date/expected.md
@@ -0,0 +1,25 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## [0.2.0] - 2022-04-06
+
+### Bug Fixes
+
+- Fix feature 2
+
+### Features
+
+- Add feature 2
+
+## [0.1.0] - 2022-04-06
+
+### Bug Fixes
+
+- Fix feature 1
+
+### Features
+
+- Add feature 1
+
+<!-- generated by git-cliff -->
diff --git a/.github/workflows/test-fixtures.yml b/.github/workflows/test-fixtures.yml
index 69b74e2f9a..18f1163a9d 100644
--- a/.github/workflows/test-fixtures.yml
+++ b/.github/workflows/test-fixtures.yml
@@ -93,6 +93,8 @@ jobs:
             command: --bump --unreleased --with-tag-message "Some text"
           - fixtures-name: test-from-context
             command: --from-context context.json
+          - fixtures-name: test-unchanged-tag-date
+            command: --tag v0.2.0
 
     steps:
       - name: Checkout