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
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 objectC
, we want a tagB
that directly points atC
but also a tagA
that points at the tagB
.
We used to miss the intermediate tagB
in some cases.What happens if we have a chain of tags (e.g., 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)
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:
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
I think you can do this with git clone --single-branch
:
--[no-]single-branch Clone only the history leading to the tip of a single branch, either specified by the --branch option or the primary branch remote’s HEAD points at. When creating a shallow clone with the --depth option, this is the default, unless --no-single-branch is given to fetch the histories near the tips of all branches. Further fetches into the resulting repository will only update the remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when --single-branch clone was made, no remote-tracking branch is created.
Note that this says you need a branch to be specified with --branch
, rather than a tag. However, the documentation for --branch
says:
--branch , -b Instead of pointing the newly created HEAD to the branch pointed to by the cloned repository’s HEAD, point to branch instead. In a non-bare repository, this is the branch that will be checked out. --branch can also take tags and detaches the HEAD at that commit in the resulting repository.
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?