* consider "git describe"... harmful? (if misused)
2024-02-03 18:43 ` bug#63775: git describe on current master says: v1.3.0-38775-g6192acf8b7 Giovanni Biscuolo
@ 2024-02-05 11:08 ` Giovanni Biscuolo
2024-02-12 9:17 ` bug#63775: git describe on current master says: v1.3.0-38775-g6192acf8b7 Simon Tournier
1 sibling, 0 replies; 3+ messages in thread
From: Giovanni Biscuolo @ 2024-02-05 11:08 UTC (permalink / raw)
To: guix-devel
[-- Attachment #1: Type: text/plain, Size: 4625 bytes --]
Hello developers,
Ipse dixit: a tag is a tag is a tag.
Sorry to stress on this but AFAIU "git describe" and it's variants is
(mis)used by some (many?) to obtain the last revision number of packages
got from a git tag on a repo, even in few upstream build config/scripts
(patched in Guix); here are just a few examples I've observed from
messages in this mailing list and our package definitions:
- https://yhetil.org/guix/7a759ffb-fca8-478d-a4aa-08e6b674da75@archlinux.org:
`git describe --tags`, which is often used for --version output
(especially in Go projects)
- https://yhetil.org/guix/87ediha5p0.wl-hako@ultrarare.space: I usually
obtain the revision number from the output of 'git describe --tags', I
think it's fine to use it when available.
- https://yhetil.org/guix/c93c18e5-8e01-45a0-b79f-05d72f6f8230@archlinux.org
The output of `git describe --always --tags --dirty` was also embedded.
Some code/comments I got running "find . -type f -exec grep --color=auto
-nH --null -e "git describe" \{\} +" in "<guix-repo>/gnu/packages", in
Emacs:
- ./audio.scm:751: ;; Ardour expects this file to exist at build time. The
revision is the output of git describe HEAD | sed
's/^[A-Za-z]*+//'
- ./build-tools.scm:589: (substitute* "src/tup/link.sh" (("`git
describe`") ,version))
- ./linux.scm:7263: ;; the checkout lacks a .git directory, breaking ‘git
describe’.
- ./axoloti.scm:500: ;; TODO: this is the output of: git describe --long
--tags --dirty --always
IMHO "git describe" should never be used to obtain the last revision
for the reasons I explained in my previous message (see a quote below):
IF you get it right is ONLY by chance (probably it's most of the times),
not by **design**; executive summary:
1. "git describe [--tag]" have a bug and doesn't traverse the graph in
topological order; for the Guix git repo this means that now the last
"git describe" tell us something like "v1.3.0-53609-gc70c513317" (the
number of commits and the commit hash may vary depending on last "git
pull"), not something like...
2. is NOT guaranteed that the last tag reported by "git describe
[--tag]" (even if the above mentioned bug is resolved) is the one
corresponding to a released revision of the software, since tags (even
annotated one) can be added by repo committers for any reason they find
useful; i.e. the last tag commited gor the Guix repo is
base-for-issue-62196. If and ONLY IF committers use a recognised
pattern for the tag - i.e. v<semver> - we can get the last (tagged)
revision from git (see below for alternative to "
Giovanni Biscuolo <g@xelera.eu> writes:
[...]
> The upstream bug report (and a reproducer) is this one:
> «Subject: [BUG] `git describe` doesn't traverse the graph in topological
> order»
> https://lore.kernel.org/git/ZNffWAgldUZdpQcr@farprobe/
>
> Another user also reported the issue and a reproducer:
> https://public-inbox.org/git/PH0PR08MB773203CE3206B8DEFB172B2F94839@PH0PR08MB7732.namprd08.prod.outlook.com/
>
> The "executive summary" is that "git describe" gets the count of "fewest
> commits different from the input commit-ish" wrong (see anso previous
> messages in this thread for details).
>
> Anyway, even if this bug was solved, I'd warmly suggest NOT to base the
> check for the latest stable Guix commit (usually tagged as v[0-9]*) on
> the result of "git describe".
>
> Today, if "guix describe"
I mean "git describe", sorry!
> had no bugs, the correct result would be:
> "base-for-issue-62196"... AFAIU :-)
>
> This is a reproducer:
>
> --8<---------------cut here---------------start------------->8---
>
> $ git describe $(git rev-list --tags --max-count=1)
> base-for-issue-62196
>
> --8<---------------cut here---------------end--------------->8---
>
> To get the value corresponding to the latest tagged version, we should
> testrict the list of tags to the ones matching the "v[0-9]*" regexp:
>
> --8<---------------cut here---------------start------------->8---
>
> $ git describe $(git rev-list --tags="v[0-9]*" --max-count=1)
> v1.4.0
>
> --8<---------------cut here---------------end--------------->8---
More efficient alternative:
--8<---------------cut here---------------start------------->8---
$ git tag --list 'v*' --sort=-creatordate | head -1
v1.4.0
--8<---------------cut here---------------end--------------->8---
[...]
Should we add some notes (a footnote?) in our Guix manual?
WDYT?
--
Giovanni Biscuolo
Xelera IT Infrastructures
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 849 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: bug#63775: git describe on current master says: v1.3.0-38775-g6192acf8b7
2024-02-03 18:43 ` bug#63775: git describe on current master says: v1.3.0-38775-g6192acf8b7 Giovanni Biscuolo
2024-02-05 11:08 ` consider "git describe"... harmful? (if misused) Giovanni Biscuolo
@ 2024-02-12 9:17 ` Simon Tournier
1 sibling, 0 replies; 3+ messages in thread
From: Simon Tournier @ 2024-02-12 9:17 UTC (permalink / raw)
To: Giovanni Biscuolo, Jonathan Brielmaier, 63775-close; +Cc: guix-devel
Hi,
On sam., 03 févr. 2024 at 19:43, Giovanni Biscuolo <g@xelera.eu> wrote:
> This is a git bug, not an issue with our repo, and for this reason (I
> hope) I'm closing this bug; please see below.
Here the explanation of the bug of “git describe”:
https://lore.kernel.org/git/20191008123156.GG11529@szeder.dev/
$ git describe d1a251a1fa
v2.23.0-135-gd1a251a1fa
$ git log --oneline v2.23.0..d1a251a1fa | wc -l
59
Uh-oh, 59 != 135.
This is happening because:
- Git is too fast ;) and the committer date has a one second
granularity, so scripts can easily create subsequent commits with
the same committer date. Case in point are the two subsequent
merge commits f3c19f85c5 and 4a3ed2bec6 at the bottom of this
simplified history snippet (kind of a hand-edited 'git log --graph
--format="%h %cd %s"'):
* d1a251a1fa 2019-09-09 12:26:36 -0700 Merge branch 'en/checkout-mismerge-fix'
|\
* | ... a big chunk of history simplified away ...
| * acb7da05ac 2019-08-16 09:58:00 -0700 checkout: remove duplicate code
* | a5e4be2f68 2019-04-25 16:41:15 +0900 Merge branch 'ab/commit-graph-fixes'
* | f3c19f85c5 2019-04-25 16:41:14 +0900 Merge branch 'ab/gc-reflog'
|/
* 4a3ed2bec6 2019-04-25 16:41:14 +0900 Merge branch 'nd/checkout-m'
- 'git describe' implements its own history traversal: it iterates
over all parents of a commit, adds any yet unseen parents to a
commit list ordered by date, and then continues with the first,
i.e. most recent commit from that list. While doing so it uses
several bits in 'commit->object.flags' to track reachability
information from several candidate tags at once, and copies these
flags from each commit to its parents; this is important to
compute the correct number of additional commits. Another
important thing is the implementation detail that
commit_list_insert_by_date() inserts a new commit after all other
commits with the same date that are already in the list.
Thanks Giovanni for pointing this out.
Cheers,
simon
^ permalink raw reply [flat|nested] 3+ messages in thread