简体   繁体   中英

Checkout a tag from a private GitHub repository

I need to clone a private repository from GitHub, but I only want to get a specific tag (so basically, cloning is actually the wrong term for it).

Now, the problem is that there are multiple options, and all of them don't really work out:

  • GitHub offers tagged versions as archives, but they are not accessible via curl or wget (at least I could not figure out how).
  • GitHub does not support archiving repositories.
  • I could run a git clone and then run a git checkout to get to the version specified by the tag, but then I download more than I need, I am in detached head state, and all the remaining stuff stays on disk. Of course, I could clean this up manually, but … well, lots of work for a trivial task.

What is the best way to achieve what I want to do?

Update

I think my question was not clear enough, hence I'm adding some more information: What I want is not only get to the revision marked by a tag, but I also want to remove the entire history. Basically, as if Git never existed, and all I ever had was this one single version of my code. Any hints?

I think you can do this with git clone --single-branch :

\n       --[no-]single-branch \n           Clone only the history leading to the tip of a single branch, either\n           specified by the --branch option or the primary branch remote's HEAD\n           points at. When creating a shallow clone with the --depth option, this\n           is the default, unless --no-single-branch is given to fetch the\n           histories near the tips of all branches. Further fetches into the\n           resulting repository will only update the remote-tracking branch for the\n           branch this option was used for the initial cloning. If the HEAD at the\n           remote did not point at any branch when --single-branch clone was made,\n           no remote-tracking branch is created.\n

Note that this says you need a branch to be specified with --branch , rather than a tag. However, the documentation for --branch says:

\n       --branch , -b  \n           Instead of pointing the newly created HEAD to the branch pointed to by\n           the cloned repository's HEAD, point to branch instead. In a\n           non-bare repository, this is the branch that will be checked out.\n           --branch can also take tags and detaches the HEAD at that commit in the \n           resulting repository.\n

The last sentence says you can use --branch with a tag. The only thing I'm not sure of is whether you can both use --single-branch and pass a tag to --branch . I guess you will have to try that to confirm. Alternatively, you will have to create a branch in the remote repository as opposed to a tag.

Update

You now say you also want to destroy the entire history. Do this afterwards.

Two ways:

Living dangerously:

git clean -xdf  # Clean out everything not in git
rm -rf .git     # remove git
git init .      # put it back
git add .       # Add all the files
git commit -a -m "Eternal sunshine of the spotless mind"

Living less dangerously

git rebase --root -i # needs recent version of git

then change every line to begin with s to squash into the original commit.

Also see How to squash all git commits into one?

git fetch --all --prune will update your local repository with all the latest branches and tags, once you have them locally you can simply check them out.

After the fetch you can list the tags with git tag -l and then git checkout a specific tag: git checkout tags/<tag_name>

Of course that you can also pull directly form the remote repo without fetching before.

you need to keep in mind that in git there are 2 types of tags:

  • regular tag (a "real" git commit)
  • annotated tag (a movable SHA-1 to any commit that you wish to use it on)

So if you checkout an annotated tag today it doesn't mean that if you checkout tag now it will be the same commit later on. keep it in mind

If you want to clone the tip of the tag (just the last commit)

git clone <repo_url> --branch <tag_name> --depth=1

Note: git clone --single-branch --branch tag can work but.. forget intermediate tags in case of tag chaining!

See commit b773dde , commit ab51783 , commit 948a7fd , commit 2076353 , commit 1962d9f (07 Sep 2016) by Jeff King ( peff ) .
(Merged by Junio C Hamano -- gitster -- in commit 9883ec2 , 15 Sep 2016)

pack-objects : walk tag chains for --include-tag

" git pack-objects --include-tag " was taught that when we know that we are sending an object C , we want a tag B that directly points at C but also a tag A that points at the tag B .
We used to miss the intermediate tag B in some cases.

What happens if we have a chain of tags (eg, tag " A " points to tag " B ", which points to commit " C ")?

We'll peel down to " C " and realize that we want to include tag " A ", but we do not ever consider tag " B ", leading to a broken pack (assuming " B " was not otherwise selected).

This is fixed in Git 2.11 (Q4 2016)


With Git 2.31 (Q1 2021), the " pack-objects " command needs to iterate over all the tags when automatic tag following is enabled, but it actually iterated over all refs and then discarded everything outside " refs/tags /" hierarchy, which was quite wasteful.

See commit be18153 (20 Jan 2021) by Jacob Vosmaer ( jacobvosmaer ) .
(Merged by Junio C Hamano -- gitster -- in commit 77db59c , 05 Feb 2021)

builtin/pack-objects.c : avoid iterating all refs

Signed-off-by: Jacob Vosmaer
Reviewed-by: Taylor Blau

In git-pack-objects , we iterate over all the tags if the --include-tag option is passed on the command line.
For some reason this uses for_each_ref which is expensive if the repo has many refs.
We should use for_each_tag_ref instead.

Because the add_ref_tag callback will now only visit tags we simplified it a bit.

The motivation for this change is that we observed performance issues with a repository on gitlab.com that has 500,000 refs but only 2,000 tags.
The fetch traffic on that repo is dominated by CI, and when we changed CI to fetch with ' git fetch --no-tags ' ( man ) we saw a dramatic change in the CPU profile of git-pack-objects.
This lead us to this particular ref walk.
More details in: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/746#note_483546598

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM