.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Git::Version::Compare 3pm" .TH Git::Version::Compare 3pm "2023-01-23" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Git::Version::Compare \- Functions to compare Git versions .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Git::Version::Compare qw( cmp_git ); \& \& # result: 1.2.3 1.7.0.rc0 1.7.4.rc1 1.8.3.4 1.9.3 2.0.0.rc2 2.0.3 2.3.0.rc1 \& my @versions = sort cmp_git qw( \& 1.7.4.rc1 1.9.3 1.7.0.rc0 2.0.0.rc2 1.2.3 1.8.3.4 2.3.0.rc1 2.0.3 \& ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Git::Version::Compare contains a selection of subroutines that make dealing with Git-related things (like versions) a little bit easier. .PP The strings to compare can be version numbers, tags from \f(CW\*(C`git.git\*(C'\fR or the output of \f(CW\*(C`git version\*(C'\fR or \f(CW\*(C`git describe\*(C'\fR. .PP These routines collect the knowledge about Git versions that was accumulated while developing Git::Repository. .SH "AVAILABLE FUNCTIONS" .IX Header "AVAILABLE FUNCTIONS" By default Git::Version::Compare does not export any subroutines. .PP All the comparison version functions die when given strings that do not look like Git version numbers (the check is done with \*(L"looks_like_git\*(R"). .SS "lt_git" .IX Subsection "lt_git" .Vb 1 \& if ( lt_git( $v1, $v2 ) ) { ... } .Ve .PP A Git-aware version of the \f(CW\*(C`lt\*(C'\fR operator. .SS "gt_git" .IX Subsection "gt_git" .Vb 1 \& if ( gt_git( $v1, $v2 ) ) { ... } .Ve .PP A Git-aware version of the \f(CW\*(C`gt\*(C'\fR operator. .SS "le_git" .IX Subsection "le_git" .Vb 1 \& if ( le_git( $v1, $v2 ) ) { ... } .Ve .PP A Git-aware version of the \f(CW\*(C`le\*(C'\fR operator. .SS "ge_git" .IX Subsection "ge_git" .Vb 1 \& if ( ge_git( $v1, $v2 ) ) { ... } .Ve .PP A Git-aware version of the \f(CW\*(C`ge\*(C'\fR operator. .SS "eq_git" .IX Subsection "eq_git" .Vb 1 \& if ( eq_git( $v1, $v2 ) ) { ... } .Ve .PP A Git-aware version of the \f(CW\*(C`eq\*(C'\fR operator. .SS "ne_git" .IX Subsection "ne_git" .Vb 1 \& if ( ne_git( $v1, $v2 ) ) { ... } .Ve .PP A Git-aware version of the \f(CW\*(C`ne\*(C'\fR operator. .SS "cmp_git" .IX Subsection "cmp_git" .Vb 1 \& @versions = sort cmp_git @versions; .Ve .PP A Git-aware version of the \f(CW\*(C`cmp\*(C'\fR operator. .SS "looks_like_git" .IX Subsection "looks_like_git" .Vb 2 \& # true \& looks_like_git(\`git version\`); # duh \& \& # false \& looks_like_git(\*(Aqv1.7.3_02\*(Aq); # no _ in git versions .Ve .PP Given a string, returns true if it looks like a Git version number (and can therefore be parsed by \f(CW\*(C`Git::Version::Number\*(C'\fR) and false otherwise. .PP It accepts the version strings from all standard Git versions and from some non-standard Gits as well, such as GitLab's embedded Git which uses a special suffix like \f(CW\*(C`.gl1\*(C'\fR. .SH "EXPORT TAGS" .IX Header "EXPORT TAGS" .SS ":ops" .IX Subsection ":ops" Exports \f(CW\*(C`lt_git\*(C'\fR, \f(CW\*(C`gt_git\*(C'\fR, \f(CW\*(C`le_git\*(C'\fR, \f(CW\*(C`ge_git\*(C'\fR, \f(CW\*(C`eq_git\*(C'\fR, and \f(CW\*(C`ne_git\*(C'\fR. .SS ":all" .IX Subsection ":all" Exports \f(CW\*(C`lt_git\*(C'\fR, \f(CW\*(C`gt_git\*(C'\fR, \f(CW\*(C`le_git\*(C'\fR, \f(CW\*(C`ge_git\*(C'\fR, \f(CW\*(C`eq_git\*(C'\fR, \f(CW\*(C`ne_git\*(C'\fR, \&\f(CW\*(C`cmp_git\*(C'\fR, and \f(CW\*(C`looks_like_git\*(C'\fR. .SH "EVERYTHING YOU EVER WANTED TO KNOW ABOUT GIT VERSION NUMBERS" .IX Header "EVERYTHING YOU EVER WANTED TO KNOW ABOUT GIT VERSION NUMBERS" .SH "Version numbers" .IX Header "Version numbers" Version numbers as returned by \f(CW\*(C`git version\*(C'\fR are in the following formats (since the \f(CW1.4\fR series, in 2006): .PP .Vb 3 \& # stable version \& 1.6.0 \& 2.7.1 \& \& # maintenance release \& 1.8.5.6 \& \& # release candidate \& 1.6.0.rc2 \& \& # development version \& # (the last two elements come from \`git describe\`) \& 1.7.1.209.gd60ad \& 1.8.5.1.21.gb2a0afd \& 2.3.0.rc0.36.g63a0e83 .Ve .PP In the \f(CW\*(C`git.git\*(C'\fR repository, several commits have multiple tags (e.g. \f(CW\*(C`v1.0.1\*(C'\fR and \f(CW\*(C`v1.0.2\*(C'\fR point respectively to \f(CW\*(C`v1.0.0a\*(C'\fR and \f(CW\*(C`v1.0.0b\*(C'\fR). Pre\-1.0.0 versions also have non-standard formats like \f(CW\*(C`0.99.9j\*(C'\fR or \f(CW\*(C`1.0rc2\*(C'\fR. .PP This explains why: .PP .Vb 3 \& # this is true \& eq_git( \*(Aq0.99.9l\*(Aq, \*(Aq1.0rc4\*(Aq ); \& eq_git( \*(Aq1.0.0a\*(Aq, \*(Aq1.0.1\*(Aq ); \& \& # this is false \& ge_git( \*(Aq1.0rc3\*(Aq, \*(Aq0.99.9m\*(Aq ); .Ve .PP \&\f(CW\*(C`git version\*(C'\fR appeared in version \f(CW1.3.0\fR. \&\f(CW\*(C`git \-\-version\*(C'\fR appeared in version \f(CW0.99.7\fR. Before that, there is no way to know which version of Git one is dealing with. .PP \&\f(CW\*(C`Git::Version::Compare\*(C'\fR converts all version numbers to an internal format before performing a simple string comparison. .SS "Development versions" .IX Subsection "Development versions" Prior to \f(CW\*(C`1.4.0\-rc1\*(C'\fR (June 2006), compiling a development version of Git would lead \f(CW\*(C`git \-\-version\*(C'\fR to output \f(CW\*(C`1.x\-GIT\*(C'\fR (with \f(CW\*(C`x\*(C'\fR in \f(CW\*(C`0 .. 3\*(C'\fR), which would make comparing versions that are very close a futile exercise. .PP Other issues exist when comparing development version numbers with one another. For example, \f(CW1.7.1.1\fR is greater than both \f(CW\*(C`1.7.1.1.gc8c07\*(C'\fR and \f(CW\*(C`1.7.1.1.g5f35a\*(C'\fR, and \f(CW1.7.1\fR is less than both. Obviously, \&\f(CW\*(C`1.7.1.1.gc8c07\*(C'\fR will compare as greater than \f(CW\*(C`1.7.1.1.g5f35a\*(C'\fR (asciibetically), but in fact these two version numbers cannot be compared, as they are two siblings children of the commit tagged \&\f(CW\*(C`v1.7.1\*(C'\fR). For practical purposes, the version-comparison methods declares them equal. .PP Therefore: .PP .Vb 3 \& # this is true \& lt_git( \*(Aq1.8.5.4.8.g7c9b668\*(Aq, \*(Aq1.8.5.4.19.g5032098\*(Aq ); \& gt_git( \*(Aq1.3.GIT\*(Aq, \*(Aq1.3.0\*(Aq ); \& \& # this is false \& ne_git( \*(Aq1.7.1.1.gc8c07\*(Aq, \*(Aq1.7.1.1.g5f35a\*(Aq ); \& gt_git( \*(Aq1.3.GIT\*(Aq, \*(Aq1.3.1\*(Aq ); .Ve .PP If one were to compute the set of all possible version numbers (as returned by \f(CW\*(C`git \-\-version\*(C'\fR) for all git versions that can be compiled from each commit in the \fIgit.git\fR repository, the result would not be a totally ordered set. Big deal. .PP Also, don't be too precise when requiring the minimum version of Git that supported a given feature. The precise commit in git.git at which a given feature was added doesn't mean as much as the release branch in which that commit was merged. .SH "SEE ALSO" .IX Header "SEE ALSO" Test::Requires::Git, for defining Git version requirements in test scripts that need \fBgit\fR. .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2016\-2023 Philippe Bruhat (BooK), all rights reserved. .SH "LICENSE" .IX Header "LICENSE" This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.