从私人 GitHub 存储库签出标签

Checkout a tag from a private GitHub repository

我需要从 GitHub 克隆一个私有存储库,但我只想获得一个特定的标签(所以基本上,cloning 实际上是错误的术语它)。

现在的问题是有多种选择,但并不是所有的选择都可行:

实现我想做的事情的最佳方法是什么?

更新

我觉得我的问题不够清楚,所以我添加了更多信息:我想要的不仅是获得标签标记的修订版,而且我还想删除整个历史记录。基本上,就好像 Git 从未存在过一样,而我所拥有的只是我的代码的一个单一版本。有什么提示吗?

认为你可以用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.

请注意,这表示您需要使用 --branch 而不是标签来指定分支。但是,--branch 的文档说:

       --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.

最后一句说你可以使用带有标签的--branch。我唯一不确定的是你们是否可以同时使用 --single-branch 并将标签传递给 --branch。我想你将不得不尝试确认。或者,您必须在远程存储库中创建一个分支而不是标签。

更新

你现在说你也想毁掉整个历史。之后再做。

两种方式:

危险的生活:

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"

生活不那么危险

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

然后将每一行更改为以 s 开头以压缩到原始提交中。

另见 How to squash all git commits into one?

git fetch --all --prune 将使用所有最新的分支和标签更新您的本地存储库,一旦您在本地拥有它们,您就可以简单地检出它们。

抓取后,您可以使用 git tag -l 列出标签,然后 git 签出特定标签:git checkout tags/<tag_name>

当然你也可以直接从远程仓库拉取而无需事先获取。

您需要记住,在 git 中有两种类型的标签:

  • 常规标签("real" git 提交)
  • 带注释的标签(可移动的 SHA-1 到您希望在其上使用的任何提交)

因此,如果您今天签出一个带注释的标签,并不意味着如果您现在签出标签,以后也会是相同的提交。记在心里

如果你想克隆标签的提示(只是最后一次提交)

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

注意:git clone --single-branch --branch tag 可以工作,但是..在标签链的情况下忘记中间标签!

参见 commit b773dde, commit ab51783, commit 948a7fd, commit 2076353, commit 1962d9f (07 Sep 2016) by Jeff King (peff)
(由 Junio C Hamano -- gitster -- in commit 9883ec2 合并,2016 年 9 月 15 日)

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 (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).

这已在 Git 2.11(2016 年第 4 季度)

中修复

使用 Git 2.31(2021 年第一季度),“pack-objects”命令需要在启用自动标签跟随时迭代所有标签,但它实际上迭代了所有 refs 然后丢弃"refs/tags/" 层次结构之外的所有内容,这非常浪费。

参见 commit be18153 (20 Jan 2021) by Jacob Vosmaer (jacobvosmaer)
(由 Junio C Hamano -- gitster -- in commit 77db59c 合并,2021 年 2 月 5 日)

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