Preetpal Singh
Preetpal Singh

Reputation: 101

How to clone latest tag in a Git repo

git ls-remote --tags git://github.com/git/git.git

lists the latest tags without cloning. I need a way to be able to clone from the latest tag directly

Upvotes: 10

Views: 6265

Answers (3)

Thermostat
Thermostat

Reputation: 557

This one-liner will get you a clone of a repo of just the latest tag.

REPO=https://github.com/namespace/repo.git && \
git clone $REPO --single-branch --branch \
$(git ls-remote --tags $REPO | cut -d/ -f3 | sort -V | tail -n1)

Explanation

  1. First we set a REPO variable. We need it twice, this reduces the chance of errors.
  2. Then we use the next command to:
    • Get the tags from the remote
    • cut away everything but the tag name from the strings
    • use sort with the natural version sorting flag
    • use tail to get the last in the sorted list
  3. That then becomes the 'branch' to clone

Tried this with a few repo's. No caveats come to mind (repo's without tags will fail of course), but do let me know if this can be improved.

Add -c advice.detachedHead=false to not get a long warning about the detached state.

Semantic version pinning

If you'd like to pin a semantic version, you can pipe the cut output through this command.

grep -E "v?[0-9]\.[0-9]+\.[0-9]+" 

You can replace each [0-9] to pin the major, minor, or patch version. For example:

MAJOR_VERSION=2
REPO=https://github.com/namespace/repo.git && \
git clone $REPO --single-branch --branch \
$(git ls-remote --tags $REPO | grep -E "v?${MAJOR_VERSION}\.[0-9]+\.[0-9]+" | cut -d/ -f3 | sort -V | tail -n1)

Would get the latest v2.x.x from that repository

Upvotes: 4

Tom Hale
Tom Hale

Reputation: 46953

Call this ~/bin/git-clone-latest-tag:

#!/bin/bash

set -euo pipefail
basename=${0##*/}

if [[ $# -lt 1 ]]; then
    printf '%s: Clone the latest tag on remote.\n' "$basename" >&2
    printf 'Usage: %s [other args] <remote>\n' "$basename" >&2
    exit 1
fi

remote=${*: -1} # Get last argument

echo "Getting list of tags from: $remote"

tag=$(git ls-remote --tags --exit-code --refs "$remote" \
  | sed -E 's/^[[:xdigit:]]+[[:space:]]+refs\/tags\/(.+)/\1/g' \
  | sort --version-sort | tail -n1)

echo "Selected tag: $tag"

# Clone as shallowly as possible. Remote is the last argument.
git clone --branch "$tag" --depth 1 --shallow-submodules --recurse-submodules "$@"

Then you can do:

% git clone-latest-tag https://github.com/python/cpython.git
Getting list of tags from: https://github.com/python/cpython.git
Selected tag: v3.8.0b1
Cloning into 'cpython'...
remote: Enumerating objects: 4346, done.
...

Upvotes: 9

Ram Vennam
Ram Vennam

Reputation: 3546

# Clone repo
$ git clone <url>

# Go into repo folder
$ cd <reponame>

# Get new tags from the remote
$ git fetch --tags

# Get the latest tag name, assign it to a variable
$ latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)

# Checkout the latest tag
$ git checkout $latestTag

Found this solution here

Upvotes: 0

Related Questions