---
name: "Git::Version::Compare"
section: "3pm"
platform: "linux"
package: "libgit-version-compare-perl"
version: "1.005-1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Git::Version::Compare"
---

# Git::Version::Compare(3pm)

Functions to compare Git versions

## NAME

Git::Version::Compare - Functions to compare Git versions

## SYNOPSIS

```
    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
    );
```

## DESCRIPTION

Git::Version::Compare contains a selection of subroutines that make dealing with Git-related things (like versions) a little bit easier.

The strings to compare can be version numbers, tags from `"git.git"` or the output of `"git version"` or `"git describe"`.

These routines collect the knowledge about Git versions that was accumulated while developing Git::Repository.

## AVAILABLE FUNCTIONS

By default Git::Version::Compare does not export any subroutines.

All the comparison version functions die when given strings that do not look like Git version numbers (the check is done with "looks\_like\_git").

### lt\_git

```
    if ( lt_git( $v1, $v2 ) ) { ... }
```

A Git-aware version of the `"lt"` operator.

### gt\_git

```
    if ( gt_git( $v1, $v2 ) ) { ... }
```

A Git-aware version of the `"gt"` operator.

### le\_git

```
    if ( le_git( $v1, $v2 ) ) { ... }
```

A Git-aware version of the `"le"` operator.

### ge\_git

```
    if ( ge_git( $v1, $v2 ) ) { ... }
```

A Git-aware version of the `"ge"` operator.

### eq\_git

```
    if ( eq_git( $v1, $v2 ) ) { ... }
```

A Git-aware version of the `"eq"` operator.

### ne\_git

```
    if ( ne_git( $v1, $v2 ) ) { ... }
```

A Git-aware version of the `"ne"` operator.

### cmp\_git

```
    @versions = sort cmp_git @versions;
```

A Git-aware version of the `"cmp"` operator.

### looks\_like\_git

```
    # true
    looks_like_git(`git version`);    # duh
    # false
    looks_like_git('v1.7.3_02');      # no _ in git versions
```

Given a string, returns true if it looks like a Git version number (and can therefore be parsed by `"Git::Version::Number"`) and false otherwise.

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 `".gl1"`.

## EXPORT TAGS

### :ops

Exports `"lt_git"`, `"gt_git"`, `"le_git"`, `"ge_git"`, `"eq_git"`, and `"ne_git"`.

### :all

Exports `"lt_git"`, `"gt_git"`, `"le_git"`, `"ge_git"`, `"eq_git"`, `"ne_git"`, `"cmp_git"`, and `"looks_like_git"`.

## EVERYTHING YOU EVER WANTED TO KNOW ABOUT GIT VERSION NUMBERS

## Version numbers

Version numbers as returned by `"git version"` are in the following formats (since the `1.4` series, in 2006):

```
    # 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
```

In the `"git.git"` repository, several commits have multiple tags (e.g. `"v1.0.1"` and `"v1.0.2"` point respectively to `"v1.0.0a"` and `"v1.0.0b"`). Pre-1.0.0 versions also have non-standard formats like `"0.99.9j"` or `"1.0rc2"`.

This explains why:

```
    # this is true
    eq_git( '0.99.9l', '1.0rc4' );
    eq_git( '1.0.0a',  '1.0.1' );
    # this is false
    ge_git( '1.0rc3', '0.99.9m' );
```

`"git version"` appeared in version `1.3.0`. `"git --version"` appeared in version `0.99.7`. Before that, there is no way to know which version of Git one is dealing with.

`"Git::Version::Compare"` converts all version numbers to an internal format before performing a simple string comparison.

### Development versions

Prior to `"1.4.0-rc1"` (June 2006), compiling a development version of Git would lead `"git --version"` to output `"1.x-GIT"` (with `"x"` in `"0 .. 3"`), which would make comparing versions that are very close a futile exercise.

Other issues exist when comparing development version numbers with one another. For example, `1.7.1.1` is greater than both `"1.7.1.1.gc8c07"` and `"1.7.1.1.g5f35a"`, and `1.7.1` is less than both. Obviously, `"1.7.1.1.gc8c07"` will compare as greater than `"1.7.1.1.g5f35a"` (asciibetically), but in fact these two version numbers cannot be compared, as they are two siblings children of the commit tagged `"v1.7.1"`). For practical purposes, the version-comparison methods declares them equal.

Therefore:

```
    # this is true
    lt_git( '1.8.5.4.8.g7c9b668', '1.8.5.4.19.g5032098' );
    gt_git( '1.3.GIT', '1.3.0' );
    # this is false
    ne_git( '1.7.1.1.gc8c07', '1.7.1.1.g5f35a' );
    gt_git( '1.3.GIT', '1.3.1' );
```

If one were to compute the set of all possible version numbers (as returned by `"git --version"`) for all git versions that can be compiled from each commit in the *git.git* repository, the result would not be a totally ordered set. Big deal.

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.

## SEE ALSO

Test::Requires::Git, for defining Git version requirements in test scripts that need **git**.

## COPYRIGHT

Copyright 2016-2023 Philippe Bruhat (BooK), all rights reserved.

## LICENSE

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
