#209 Possible error: %changelog not in descending chronological order
Opened 2 years ago by churchyard. Modified a year ago

When the commits are re-ordered not to be in descending chronological order, which is completely valid state of commits, the %changelog is generated in non-descending chronological order, which is and invalid state of %changelog.

Reproducer:

[rust-ammonia (rawhide)]$ YESTERDAY="Sun Jul 18 11:03:31 CEST 2021"

[rust-ammonia (rawhide)]$ git commit --allow-empty -m 'This pull request was opened today'
[rawhide 5791b78] This pull request was opened today

[rust-ammonia (rawhide)]$ GIT_COMMITTER_DATE="$YESTERDAY" git commit -a --date "$YESTERDAY" --allow-empty -m 'This pull request was opened yesterday'
[rawhide 1c1e42b] This pull request was opened yesterday
 Date: Sun Jul 18 11:03:31 2021 +0200

[rust-ammonia (rawhide)]$ git l
* 1c1e42b 2021-07-18 Miro Hrončok - This pull request was opened yesterday (HEAD -> rawhide)
* 5791b78 2021-07-19 Miro Hrončok - This pull request was opened today
* 2add49a 2021-07-09 Fabio Valentini - Update to version 3.1.2; Fixes RHBZ#1980546
...

[rust-ammonia (rawhide)]$ rpmautospec generate-changelog .
* Sun Jul 18 2021 Miro Hrončok <miro@hroncok.cz> 3.1.2-3
- This pull request was opened yesterday

* Mon Jul 19 2021 Miro Hrončok <miro@hroncok.cz> 3.1.2-2
- This pull request was opened today

* Thu Jul 08 2021 Fabio Valentini <decathorpe@gmail.com> 3.1.2-1
- Update to version 3.1.2; Fixes RHBZ#1980546
...

[rust-ammonia (rawhide)]$ fedpkg srpm


error: %changelog not in descending chronological order
setting SOURCE_DATE_EPOCH=1626566400
Wrote: /home/churchyard/rpmbuild/fedora-scm/rust-ammonia/rust-ammonia-3.1.2-3.fc35.src.rpm

[rust-ammonia (rawhide)]$ rpm -q --changelog rust-ammonia-3.1.2-2.fc35.src.rpm
(no changelog)

As a possible workaround of this problem, any to be generated changelog entry that is "higher" than the previous one but "older" needs to be clamped to the date of the previous changelog entry.


Can we fix this on the RPM side, by relaxing its requirement for an ordered changelog?

I am not sure the RPM folks would want that.

Hmm, you could be right about that. Maybe rpmautospec should look at the left-most parent commits only (at least optionally), that would allow to bring in problematic history through merges.

#263 might also help.

Hmm, you could be right about that. Maybe rpmautospec should look at the left-most parent commits only (at least optionally), that would allow to bring in problematic history through merges.

#263 might also help.

Even if rpmautospec looks at git rev-list --first-parent only, topological order (in this case: linear) need not coincide with chronological order (author date).

rpm's changelog date is a mix of author and commit/build date: Nothing ensures that changelog dates correspond to any particular event or action, unless you use bumpspec. In fact, it's very typical to bring in changes from other branches which are out of chronological order - that is, the date of the original change (which you might want to record) is out of order and different from the date of the merge or cherry-pick.

As a result, it's not clear why rpm should even insist on chronological order. It's ill-conceived. But you are right in pointing out that it probably won't change.

To increase the chance that topological == chrononological, autospec could look at the commit-dates (not author-dates) along first-parent history. author/commit match unless you rewrite, and commit/topo match unless you forcefully change commit dates or have clock issues.

We could use some tooling to bring in commit descriptions from the side branch commits to the merge commit then because otherwise they won't show up in the changelog anymore.

It would be nice if the design docs documented how this is supposed to work. I did a test now, and rpmautospec generate-changelog follows the second parent:

$ ~/python/rpmautospec/run-rpmautospec.py generate-changelog | head -n5
* Tue Nov 08 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 252.1-1
- Version 252.1 (just some small fixes).

* Mon Oct 31 2022 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 252-1
- Version 252

$ git log --pretty=oneline --decorate --graph | head -4
*   b5ab12aa795d7ada113cff9a102fb848e25b1694 (HEAD -> f37) Merge
|\  
| * c6d202c6ace19b9f02587069308df846b97ddd77 (origin/rawhide, origin/main, rawhide) Version 252.1
| * eeb9a47dfb0d9a0543b0ef6594a2408080856e07 Version 252

$ git log --pretty=fuller -1                           
commit b5ab12aa795d7ada113cff9a102fb848e25b1694 (HEAD -> f37)
Merge: d19e77ca88 c6d202c6ac
Author:     Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
AuthorDate: Thu Nov 10 11:15:46 2022 +0100
Commit:     Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
CommitDate: Thu Nov 10 11:15:46 2022 +0100

    Merge

It completely ignores all the commits on the first parent. They don't appear in the generated changelog at all. This looks like a bug, because those commits were all used to build packages in koji.

--

As a result, it's not clear why rpm should even insist on chronological order. It's ill-conceived.

Agreed. I think this should be subject to linting and such, but not cause any hard error.

rpm's changelog date is a mix of author and commit/build date: Nothing ensures that changelog dates correspond to any particular event or action

Yes. Because of commit cherry-picking and merges and faulty clocks, rpmautospec must be fine with any ordering of both author and committer timestamps. In principle committer timestamp are more likely to be sequential in time, but even there exceptions will happen.

I think the only reasonable answer is to clamp the times to be chronologically consistent. Essentially, even if the author or committer timestamps say differently, we know that commits can only be applied sequentially, thus we know that parents are older than children in the graph in any given history timeline.

One thing that could be easily done is to pick the commit timestamp if the author timestamp is chronologically inconsistent. This commit timestamp is most likely the time when a cherry-picked commit was added to the branch, and it's the reasonable thing to use for a changelog date.

To deal with cases where neither timestamp gives a chronologically consistent sequence:

One option would be to increase the timestamp of changelog entries to at least the timestamp of the previous entry. The justification for this is that if we assume that commit timestamps are genuine (i.e. not made with a faulty clock), we know that a commit with an earlier timestamp than parent must have been cherry-picked, and the date when the cherry-pick happened is more relevant than the date of the original commit. I think this is the best approach.

Second option would be to decrease the timestamp of changelog entries to be before the timestamp of the next entry. The justification for this is that the last changelog entry is used for $SOURCE_DATE_EPOCH, with the assumption that that date is the time of the last of the modification of the package, and changelog entries newer than that date would be inconsistent. I don't prefer this option because the justification is weak: $SOURCE_DATE_EPOCH is just a technical detail and users don't care about it.

Login to comment on this ticket.

Metadata