2103

I'm trying to figure out how I can download a particular tag of a Git repository - it's one version behind the current version.

I saw there was a tag for the previous version on the git web page, with object name of something long hex number.

But the version name is "Tagged release 1.1.5" according the site.

I tried a command like this (with names changed):

git clone http://git.abc.net/git/abc.git my_abc

And I did get something - a directory, a bunch of subdirectories, etc.

If it's the whole repository, how do I get at the version I'm seeking? If not, how do I download that particular version?

Neil Graham
  • 593
  • 1
  • 5
  • 17
Jack BeNimble
  • 35,733
  • 41
  • 130
  • 213
  • 11
    I develop on a completely different repo then the production, so my production didn't know any tags when I tried to use git checkout. The solution was to use "git pull --tags" then use git checkout. – capitalaudience.com Nov 19 '11 at 09:35
  • 13
    "git fetch --tags" works too – John Erck Oct 26 '12 at 20:37
  • 17
    To avoid cloning the whole repository then switching to a tag, you can directly do a `clone -b "Tagged release 1.1.5" http://git.abc.net/git/abs.git my_abc`. This will only work if you don't have a branch with the same name of course (depending on your methodology, this may never happen). – RedGlyph Oct 05 '13 at 16:37
  • 3
    @RedGlyph Thanks i will try it. Else we can do like this. `git checkout -b new-branch tag-name`. Now clone your new-branch. When ever we want we can delete the new-branch. – Kalidasan Dec 19 '13 at 07:12

16 Answers16

3045
$ git clone

will give you the whole repository.

After the clone, you can list the tags with $ git tag -l and then checkout a specific tag:

$ git checkout tags/<tag_name>

Even better, checkout and create a branch (otherwise you will be on a branch named after the revision number of tag):

$ git checkout tags/<tag_name> -b <branch_name>
Edric
  • 24,639
  • 13
  • 81
  • 91
besen
  • 32,084
  • 1
  • 21
  • 12
  • 16
    Yep. git is different to subversion in this respect. A svn tag basically copies the files to a new folder, so you can svn checkout a specific bunch of files, whereas git tags are simply pointers to specific revisions. – dbr Apr 27 '09 at 02:17
  • @Renato, after git checkout , can work on the same and commit to it, just treating as a ?? I thought is given for a special commit(as a release), but treating that as a branch is confusing and opposite right? – Nanda Kishore Feb 23 '10 at 12:56
  • 5
    What if you have a branch and a tag that have the same name? If you just say "git checkout " it says "warning: refname '' is ambiguous. Switched to branch ''" -- how do you tell it to switch to the tag instead? – Tyler Nov 24 '10 at 18:35
  • 1
    Renato, `git checkout ` results in a *detached head* state which means you cannot retain any commits that you make to this repository. Answer http://stackoverflow.com/questions/791959/how-to-use-git-to-download-a-particular-tag/792030#792030 suggests how to avoid a detached head state. – Derek Mahar Apr 04 '11 at 17:44
  • Tip: If the repository is on the same machine *and* you need a read only copy, use `git clone -s -l` - for me it cuts about 80% of the time spent cloning. – ripper234 Dec 06 '11 at 16:23
  • 56
    when doing a checkout and as Derek mentioned, the repo goes into a "detached head" state. instead, add the `-b` flag telling git to create a new branch and specify a branch name: `git checkout -b ` – hellatan May 13 '12 at 17:42
  • 24
    @hellatan You should only do that when you actually want to create a branch, but most of the time you probably don't. Running in "detached head" state won't hurt you, and is likely exactly what you want if you just want to check some git history. – machineghost Jul 01 '13 at 22:12
  • If i do checkout tags/ after clone. How to I get back point to HEAD of branch instead of tag? – Karun Sep 13 '13 at 09:48
  • This answer brings a solution that is viable on small repositories only. – develCuy Jul 03 '14 at 02:11
  • 4
    In git version `1.8.3.5` and newer, the `--branch ` should allow you to download the repository starting at your `` as the repo HEAD; combined with `--depth 1` will do a shallow tag checkout. See http://stackoverflow.com/a/21699307/1695680 – ThorSummoner Oct 02 '14 at 20:33
  • Make sure you fetch the tags first with `git fetch --all` – cevaris Feb 24 '15 at 16:57
  • 2
    Strange, that ProGit v2 book says exactly that `You can’t really check out a tag in Git` – Vladislav Rastrusny Sep 17 '15 at 14:37
  • @DerekMahar I have not been able to find any documentation associated with "git checkout tags/" -- please let us know where to read about this command. Also, please clarify the relationship between result of this command and the result of the command recommended by the git book (2nd edition) at https://git-scm.com/book/en/v2/Git-Basics-Tagging#Checking-out-Tags : "git checkout -b " – user1823664 Jan 10 '16 at 17:17
  • @user1823664, you can checkout a tag, but as I mentioned in http://stackoverflow.com/questions/791959/download-a-specific-tag-with-git/792027?noredirect=1#comment6299549_792027, this creates a detached head, which leaves your working directory in practically a read-only state. See http://stackoverflow.com/a/792030/107158 to checkout a tag and avoid a detached head. – Derek Mahar Jan 11 '16 at 18:01
  • 1
    @user1823664, `tags/` must be an old or alternative way to refer to tags in a repository. Usually, I just use a `` like `1.2.1`. – Derek Mahar Jan 11 '16 at 18:04
  • What should we do if the repository has like 50k commits and will take forever to download it entirely? – Victor Feb 07 '16 at 10:29
  • `tags/` is important for identifying the tag. `origin` not required, as in case of branch-checkout. – parasrish Oct 09 '17 at 05:46
  • I particularly like the version that creates a branch on that tag. – earl3s Dec 20 '17 at 17:58
444
git clone --branch my_abc http://git.abc.net/git/abc.git

Will clone the repo and leave you on the tag you are interested in.

Documentation for 1.8.0 of git clone states.

--branch can also take tags and detaches the HEAD at that commit in the resulting repository.

Knu
  • 14,806
  • 5
  • 56
  • 89
Toni
  • 4,467
  • 1
  • 13
  • 2
  • 9
    This does (at least now) work for tags, though you end up in a detached HEAD state. – mxcl Jun 24 '13 at 23:31
  • 81
    FYI: Also specify `--depth 1` to avoid downloading any non-current commits. – Asclepius Mar 27 '14 at 23:19
  • 5
    This indeed does *not* work with tags. Only branches. Edit: It looks like only newer versions of git supports that. – lzap Jul 08 '14 at 09:05
  • We can also edit .git/config (or somehow configure it) to do a shallow clone of two or more tags, if that might be needed, upgrade a shallow clone to full clone, etc. – Sam Watkins Jan 29 '15 at 11:41
  • you can also specify the branch you want along with the tag. Like `git clone --branch my_abc http://git.abc.net/git/abc.git -b quality` quality is the name of the branch we want btw. – hazimdikenli Nov 13 '19 at 11:19
225

For checking out only a given tag for deployment, I use e.g.:

git clone -b 'v2.0' --single-branch --depth 1 https://github.com/git/git.git

This seems to be the fastest way to check out code from a remote repository if one has only interest in the most recent code instead of in a complete repository. In this way, it resembles the 'svn co' command.

Note: Per the Git manual, passing the --depth flag implies --single-branch by default.

--depth

Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.

Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
Yuan HOng
  • 2,327
  • 1
  • 11
  • 2
  • 15
    `--depth n` implies `--single-branch`. You don't need both. – Niyaz Oct 05 '18 at 01:27
  • 4
    @RyanNerd +1 :) Also, just a note for anyone else who spent the last hour figuring this out: do not quote the branch/tag name if running this command on Windows. It will literally include the quotes as-is when looking for the branch/tag – Ruslan Nov 07 '18 at 20:29
  • 1
    I am trying to clone as part of a script for deployment. Is there a way to hide the 'detached head' message? I have tried: `git clone -b 'v2.0' --quiet --depth 1 https://github.com/git/git.git` That doesn't work though. – saltedlolly Nov 14 '21 at 14:23
  • @saltedlolly there's an option for this: `git clone -c advice.detachedHead=false --depth 1 -b v2.0 https://github.com/git/git.git` – Winand Aug 16 '23 at 07:15
99

I'm not a git expert, but I think this should work:

git clone http://git.abc.net/git/abc.git
cd abc
git checkout my_abc 

OR

git clone http://git.abc.net/git/abc.git
cd abc
git checkout -b new_branch my_abc

The second variation establishes a new branch based on the tag, which lets you avoid a 'detached HEAD'. (git-checkout manual)

Every git repo contains the entire revision history, so cloning the repo gives you access to the latest commit, plus everything that came before, including the tag you're looking for.

grossvogel
  • 6,694
  • 1
  • 25
  • 36
  • 4
    Thx. I needed to use `git checkout -b b1.5.0 v1.5.0` when checking out a version within a 'gh-pages' branch to successfully push to Github Pages. This Gist I wrote up might help others re: branch/tag/submodules... https://gist.github.com/1064750 – Chris Jacob Jul 05 '11 at 17:15
  • 4
    I don't think this is completely accurate (for e.g. pasting into terminal) since you gotta `cd` into `abc/` first before you can checkout a branch – Steven Lu Apr 20 '14 at 07:01
  • @StevenLu You are correct of course. I was going for concepts rather than cut-and-paste, but it might as well be as accurate as possible. I've added the `cd`. – grossvogel Aug 07 '14 at 17:09
83

You can use git archive to download a tar ball for a given tag or commit id:

git archive --format=tar --remote=[hostname]:[path to repo] [tag name] > tagged_version.tar

You can also export a zip archive of a tag.

  1. List tags:

    git tag
    
    0.0.1
    0.1.0
    
  2. Export a tag:

    git archive -o /tmp/my-repo-0.1.0.zip --prefix=my-repo-0.1.0/ 0.1.0
    
  3. Notes:

    • You do not need to specify the format. It will be picked up by the output file name.
    • Specifying the prefix will make your code export to a directory (if you include a trailing slash).
Jeremy Postlethwaite
  • 1,204
  • 1
  • 10
  • 6
Chris J
  • 9,164
  • 7
  • 40
  • 39
  • 3
    This command does not work with submodules, see http://stackoverflow.com/questions/1591387/need-to-handle-git-submodules-in-git-archive – Zitrax Jan 13 '10 at 14:56
  • 3
    But git archive also removes the version control, so you can't just do another git checkout to upgrade to the next tag. – idbrii Apr 06 '11 at 21:37
  • 10
    Yes you lose version control but the time git archive saves compared to git clone is ABSOLUTELY UNBELIEVABLE! +1 – MarcH Mar 21 '13 at 11:28
  • This is SO CLOSE to what I want, except that `git archive` is asking me for a password when all I want to do is download from a public repo. How can I make it use http instead of ssh? – robru Feb 21 '14 at 18:26
  • 1
    This fails with the `fatal: Operation not supported by protocol.` and `Unexpected end of command stream` errors. Alternatively, it can also return the `fatal: The remote end hung up unexpectedly` error. – Asclepius Mar 27 '14 at 21:41
  • Can the git archive command be used to specify a particular branch (say 'develop' ) for which we want to extract the tar from the remote ? – tauseef_CuriousGuy Mar 13 '18 at 14:39
59

Use the --single-branch switch (available as of Git 1.7.10). The syntax is:

git clone -b <tag_name> --single-branch <repo_url> [<dest_dir>] 

For example:

git clone -b 'v1.9.5' --single-branch https://github.com/git/git.git git-1.9.5

The benefit: Git will receive objects and (need to) resolve deltas for the specified branch/tag only - while checking out the exact same amount of files! Depending on the source repository, this will save you a lot of disk space. (Plus, it'll be much quicker.)

eyecatchUp
  • 10,032
  • 4
  • 55
  • 65
  • 4
    Whoever downvoted/downvotes this answer: Please also leave a comment with a brief explanation for the downvote. _(Just asking, because I'm a bit confused. Because, afaik, this is the best solution for the given problem. And if you don't think so, I'd like to know why.)_ Many thanks. – eyecatchUp Nov 16 '16 at 11:35
  • 7
    Don't try to make too much sense of the downvotes .. your answer is very good, their downvotes are likely unsubstantiated .. that's life on SOF.. – WestCoastProjects May 24 '17 at 12:27
34

first fetch all the tags in that specific remote

git fetch <remote> 'refs/tags/*:refs/tags/*'

or just simply type

git fetch <remote>

Then check for the available tags

git tag -l

then switch to that specific tag using below command

git checkout tags/<tag_name>

Hope this will helps you!

tk_
  • 16,415
  • 8
  • 80
  • 90
19

If your tags are sortable using the linux sort command, use this:

git tag | sort -n | tail -1

eg. if git tag returns:

v1.0.1
v1.0.2
v1.0.5
v1.0.4

git tag | sort -n | tail -1 will output:

v1.0.5

git tag | sort -n | tail -2 | head -1 will output:

v1.0.4

(because you asked for the second most recent tag)

to checkout the tag, first clone the repo, then type:

git checkout v1.0.4

..or whatever tag you need.

Jake Wilson
  • 88,616
  • 93
  • 252
  • 370
Peter Johnson
  • 2,673
  • 22
  • 14
  • 26
    Until you reach v1.0.10, and then bad things happen :) – Laurent Grégoire Mar 22 '12 at 07:37
  • 10
    To have your tags sorted chronologically : `git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags` – Bob G Jun 13 '13 at 13:39
  • One-liner to automatically checkout the latest version, `git checkout \`git tag | sort -n | tail -1\`` – weiji14 Jul 21 '17 at 01:39
  • You might want to use `sort -V` instead of `sort -n`. The former correctly handles versions, which are not necessarily numeric, e.g. "1.2.3". It also understands that "0.4.10" goes after "0.4.1" and not after "0.4.2" which `-n` will give you. – soquel Sep 15 '17 at 09:23
17
git fetch <gitserver> <remotetag>:<localtag>

===================================

I just did this. First I made sure I knew the tag name spelling.

git ls-remote --tags gitserver; : or origin, whatever your remote is called

This gave me a list of tags on my git server to choose from. The original poster already knew his tag's name so this step is not necessary for everyone. The output looked like this, though the real list was longer.

8acb6864d10caa9baf25cc1e4857371efb01f7cd    refs/tags/v5.2.2.2
f4ba9d79e3d760f1990c2117187b5010e92e1ea2    refs/tags/v5.2.3.1
8dd05466201b51fcaf4ca85897347d82fcb29518    refs/tags/Fix_109
9b5087090d9077c10ba22d99d5ce90d8a45c50a3    refs/tags/Fix_110

I picked the tag I wanted and fetched that and nothing more as follows.

git fetch gitserver Fix_110

I then tagged this on my local machine, giving my tag the same name.

git tag Fix_110 FETCH_HEAD

I didn't want to clone the remote repository as other people have suggested doing, as the project I am working on is large and I want to develop in a nice clean environment. I feel this is closer to the original questions "I'm trying to figure out how do download A PARTICULAR TAG" than the solution which suggests cloning the whole repository. I don't see why anyone should have to have a copy of Windows NT and Windows 8.1 source code if they want to look at DOS 0.1 source code (for example).

I also didn't want to use CHECKOUT as others have suggested. I had a branch checked out and didn't want to affect that. My intention was to fetch the software I wanted so that I could cherry-pick something and add that to my development.

There is probably a way to fetch the tag itself rather than just a copy of the commit that was tagged. I had to tag the fetched commit myself. EDIT: Ah yes, I have found it now.

git fetch gitserver Fix_110:Fix_110

Where you see the colon, that is remote-name:local-name and here they are the tag names. This runs without upsetting the working tree etc. It just seems to copy stuff from the remote to the local machine so you have your own copy.

git fetch gitserver --dry-run Fix_110:Fix_110

with the --dry-run option added will let you have a look at what the command would do, if you want to verify its what you want. So I guess a simple

git fetch gitserver remotetag:localtag

is the real answer.

=

A separate note about tags ... When I start something new I usually tag the empty repository after git init, since

git rebase -i XXXXX 

requires a commit, and the question arises "how do you rebase changes that include your first software change?" So when I start working I do

git init
touch .gitignore
[then add it and commit it, and finally]
git tag EMPTY

i.e. create a commit before my first real change and then later use

git rebase -i EMPTY 

if I want to rebase all my work, including the first change.

Ivan
  • 4,383
  • 36
  • 27
16

I checked the git checkout documentation, it revealed one interesting thing:

git checkout -b <new_branch_name> <start_point> , where the <start_point> is the name of a commit at which to start the new branch; Defaults to HEAD

So we can mention the tag name( as tag is nothing but a name of a commit) as, say:

>> git checkout -b 1.0.2_branch 1.0.2
later, modify some files
>> git push --tags

P.S: In Git, you can't update a tag directly(since tag is just a label to a commit), you need to checkout the same tag as a branch and then commit to it and then create a separate tag.

Nanda Kishore
  • 2,789
  • 5
  • 38
  • 61
  • 1
    Or if you don't expect to make any changes and you just want to look at what the code looked like at that tag, you can just checkout the tag without creating a branch. You'll get some text explaining that you're in "detached head" state, and you can always create the branch later if you want to. – Tyler Nov 24 '10 at 18:30
9

Working off of Peter Johnson's answer, I created a nice little alias for myself:

alias gcolt="git checkout $(git tag | sort -V | tail -1)"

aka 'git checkout latest tag'.

This relies on the GNU version of sort, which appropriately handles situations like the one lOranger pointed out:

v1.0.1
...
v1.0.9
v1.0.10

If you're on a mac, brew install coreutils and then call gsort instead.

billkw
  • 3,350
  • 3
  • 28
  • 32
7

try:

git clone -b <name_of_the_tag> <repository_url> <destination>
Kamil Zając
  • 253
  • 1
  • 3
  • 7
4

Checking out Tags

If you want to view the versions of files a tag is pointing to, you can do a git checkout, though this puts your repository in “detached HEAD” state, which has some ill side effects:

$ git checkout 2.0.0
Note: checking out '2.0.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final

$ git checkout 2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... add atlas.json and cover image

In “detached HEAD” state, if you make changes and then create a commit, the tag will stay the same, but your new commit won’t belong to any branch and will be unreachable, except for by the exact commit hash. Thus, if you need to make changes—say you’re fixing a bug on an older version, for instance—you will generally want to create a branch:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

If you do this and make a commit, your version2 branch will be slightly different than your v2.0.0 tag since it will move forward with your new changes, so do be careful.

artamonovdev
  • 2,260
  • 1
  • 29
  • 33
3

I do this is via the github API:

curl -H "Authorization: token %(access_token)s" -sL -o /tmp/repo.tar.gz "http://api.github.com/repos/%(organisation)s/%(repo)s/tarball/%(tag)s" ;\
tar xfz /tmp/repo.tar.gz -C /tmp/repo --strip-components=1 ; \
J0hnG4lt
  • 4,337
  • 5
  • 24
  • 40
  • 1
    This works for branches and tags, but not head of master which needs a tag created against it. Imho quite elegant way to get minimally sized version. – J0hnG4lt Apr 08 '13 at 14:51
2

I frequently used one

git clone  --branch <tag_name> <repo_url>
Balaji
  • 9,657
  • 5
  • 47
  • 47
-2

I did as below

git checkout tags/20210511 -b 20210511-release
Rajitha Bhanuka
  • 714
  • 10
  • 11