72

I'm writing a shell script and I'm looking to checkout the latest version of repo. Specifically I want to break this process apart into multiple steps.

  1. I want to save the repositories latest tag into a variable
  2. Print out Checking out version: XX
  3. Checkout the latest tag

I've seen similar questions but I don't see how to save the name of the tag into a variable (probably because I'm a noob with shell scripts).

Community
  • 1
  • 1
BFTrick
  • 5,211
  • 6
  • 24
  • 28
  • possible duplicate of [How to get the latest tag name in current branch in Git?](http://stackoverflow.com/questions/1404796/how-to-get-the-latest-tag-name-in-current-branch-in-git). Only duplicate because you explicitly require `I want to save the repositories latest tag into a variable `, the rest is just Bash. – Ciro Santilli OurBigBook.com Jun 06 '14 at 12:20

5 Answers5

138
# Get new tags from remote
git fetch --tags

# Get latest tag name
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)

# Checkout latest tag
git checkout $latestTag
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Josef Ježek
  • 2,208
  • 2
  • 17
  • 10
36

git describe --tags should give you info.

bash/ shell script:

#!/bin/bash
...
latesttag=$(git describe --tags)
echo checking out ${latesttag}
git checkout ${latesttag}
ericn
  • 12,476
  • 16
  • 84
  • 127
exussum
  • 18,275
  • 8
  • 32
  • 65
  • 1
    But how do I save step 1 into a variable? I know how to print it to the screen. – BFTrick Jul 02 '13 at 16:36
  • Does anyone know if you need to `git fetch --tags` before doing this? – Steven Linn Jan 20 '15 at 22:41
  • No, the tag your currently on has to already be in the history – exussum Dec 03 '15 at 18:04
  • if you are on oh-my-zsh, then you can do something like `git checkout \`gdct\`` – elquimista Dec 27 '16 at 07:11
  • 2
    I would `git checkout master;git pull` then the rest of your script – lrkwz Jan 24 '18 at 13:20
  • 2
    If your latest commit has no tag, `git descibe --tags` outputs a sortable description on base of that latest tag with the number of commits since that tag. The answer of @josef-ježek should be the accepted answert – Lars Mar 27 '20 at 09:19
  • 1
    Would be better to use `git describe --tag --abbrev=0` to get rid of the shorthash if the latest commit is not tagged. – ruohola Jan 26 '22 at 16:51
  • Not working for this repo: https://git.zx2c4.com/password-store `$ git describe --tags` gives `1.7.4-10-gdddca73` but the tag is `1.7.4` – user1767316 Nov 05 '22 at 20:58
  • That means you are on master. 10 commits after the tag. See the comment above. – exussum Nov 06 '22 at 07:31
16

In some repositories the git describe --tags gives no info and a simple git tag | tail -1 can get you the wrong tag as git sorts tags in a strange way.

For me the best command is a variation of the tail one

VERSION=$(git tag | sort -V | tail -1)

  • sort: invalid option -- V – pronebird Feb 07 '15 at 16:20
  • IF your versions are X.X.X: `VERSION=$(git tag | grep "^[0-9]\+\.[0-9]\+\.[0-9]\+$" | sort -t. -k 1,1n -k 2,2n -k 3,3n | tail -1)` – Mark C Jul 24 '15 at 13:13
  • I really liked this solution because it returns empty if there are no tags found - making it an easy decision to revert to a master branch if no releases / tags have been cut yet – amurrell Mar 07 '19 at 21:33
  • this should work: ```git tag --list '[vV]*' --sort=v:refname |tail -1 ``` use --list if you want to filter by certain patterns – Qiang Li Oct 14 '19 at 17:43
4
git tag --contains | tail -1

git tag --contains lists all tags in the current branch, tail -1 limits the count of output results to be 1,and it will be the latest one.

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Antutu
  • 49
  • 1
  • 2
2

In order to put information into a variable, you assign it:

myvar=myvalue

However, you want to calculate the value to assign, you're not just assigning a constant to the variable. In your case, you want to assign the output of a command to the variable.

First, you have to figure out how to get the last tag name. I'll leave that up to you, as you haven't said anything about how the tag names are created.

Then once you have a command that gives the last tag name, you need to assign the name into a variable. Bash does that with "command substitution".

For example: thetagname=$( command_to_get_tag_name )

So if you were to just take the last tag that git reports like this:

git tag | tail -1

then you could assign it to a variable like this:

thetagname=$( git tag | tail -1)

and you could use/see the value like this:

echo $thetagname

or as user1281385 says, like this:

echo ${thetagname}

The two methods are the same, except that the second way allows you to combine literal text with the variable value:

echo ${thetagname}ing

which will append "ing" to the contents of $thetagname. The braces are necessary in order to prevent bash from thinking that "thetagnameing" is the variable.

The bash man page has a section called EXPANSION, in which it explains the 7 kinds of expansion. Command substitution is one of them. The bash man page is rather big, and indeed repeats all the interesting keywords multiple times, so it is really annoying to search for stuff in it. Here are a couple of tips on how to find the EXPANSION section (and learn a bit about the pager "less"):

Start the manual reader reading the bash man page like this:

man bash

Search for the term 'EXPANSION' at the beginning of a line once you're in the reader by typing /^EXPANSION into the display. Once you type /, you will see a / at the bottom of the screen, but the man page will still be there. That is the command to search for a pattern. Then you type ^EXPANSION, and you will see that at the bottom of the screen as well. ^ means "search for things at the beginning of the line" and EXPANSION means "look for the literal string "EXPANSION". Then type <enter> - and you should be at the first occurence of the term EXPANSION that occurs at the beginning of the line. Here it describes all the kinds of expansion that the bash shell does on your line after you type it and before it executes the transformed command.

When in the pager, you can type h to get a list of the possible commands.

I hope this wasn't too basic. If you haven't seen it before, it's hard to figure out.

Brenda J. Butler
  • 1,475
  • 11
  • 20
  • 1
    This won't work if you have tags like `v1.15.0` and `v1.9.0` -- you'll see `v1.9.0` come first. – connorbode Mar 16 '18 at 02:28
  • 1
    I did say "First, you have to figure out how to get the last tag name. I'll leave that up to you, as you haven't said anything about how the tag names are created." and "So *if* you were to just take the last tag that git reports like this:" [emphasis added]. The method given (pipe git tag to tail) is a stand-in for the person's own method, for demonstration purposes. – Brenda J. Butler May 13 '18 at 13:39