从私有GitHub仓库检出一个标签

3

我需要从GitHub克隆一个私有存储库,但我只想获取一个特定的标签(因此,克隆实际上是错误的术语)。

现在,问题在于有多个选项,它们都不能真正解决问题:

  • GitHub提供带有标签版本的存档,但无法通过curlwget访问(至少我找不到方法)。
  • GitHub不支持存储库的归档。
  • 我可以运行git clone,然后运行git checkout以获取由标签指定的版本,但然后我下载了更多内容,我处于分离的head状态,并且所有剩余的东西都留在磁盘上。当然,我可以手动清理这个,但对于一个微不足道的任务来说,这需要大量的工作。

如何才能最好地实现我想要做的事情?

更新

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

3个回答

5
我认为您可以使用git clone --single-branch来完成此操作:
       --[no-]single-branch
           仅克隆到单个分支的最新历史记录,该分支可以由--branch选项或主分支远程的HEAD指向指定。当使用--depth选项创建浅克隆时,默认情况下以此方式进行,除非通过--no-single-branch获取所有分支的附近提示历史记录。进一步获取到结果存储库中只会更新用于初始克隆的分支的远程跟踪分支。如果--single-branch克隆时,远程服务器的HEAD没有指向任何分支,则不会创建远程跟踪分支。

请注意,这里需要使用--branch指定一个分支,而不是标签。但是,--branch的文档说明如下:

       --branch , -b 
           将新创建的HEAD指向分支,而不是克隆存储库的HEAD所指向的分支。在非裸存储库中,这是将要检出的分支。--branch也可以接收标记,并将结果存储库中的HEAD断开连接到该提交。

最后一句话说您可以使用标签和--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开头,以压缩到原始提交中。
另请参见如何将所有git提交压缩成一个?

谢谢您的回复,我已经更新了我的问题(对于一开始没有那么准确表示抱歉)。 - Golo Roden
好的,现在我已经让它按照我想要的方式工作了。谢谢你的帮助 :-)) - Golo Roden

2

git fetch --all --prune会将你的本地仓库更新到最新的分支和标签,一旦你在本地有了它们,你就可以简单地检出它们。

在获取(fetch)后,您可以使用git tag -l列出标签,然后检出特定标签:git checkout tags/<tag_name>

当然,您也可以直接从远程存储库(pull)拉取,而无需先获取(fetch)。

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

  • 普通标签(一个“真正”的git提交)
  • 注释标签(可移动SHA-1到任何您希望使用它的提交)

因此,如果您今天检出一个注释标签,这并不意味着如果您现在检出标签,它将是以后相同的提交。请记住这一点。

如果您想克隆标签的末尾(commit的最后一个),则需要执行以下操作:

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


感谢您的回复,我已经更新了我的问题(对于一开始没有那么精确表示抱歉)。 - Golo Roden

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

查看commit b773dde, commit ab51783, commit 948a7fd, commit 2076353, commit 1962d9f(2016年9月7日)由Jeff King(peff)提交。
(由Junio C Hamano -- gitster --合并于commit 9883ec2,2016年9月15日)

pack-objects: 对于 --include-tag 遍历标签链

当我们知道要发送一个对象 C 时,"git pack-objects --include-tag" 命令会同时打包直接指向 C 的标签 B 和指向标签 B 的标签 A
在某些情况下,我们会错过中间的标签 B

如果我们有一条标签链(比如标签 "A" 指向标签 "B",后者又指向提交 "C")会发生什么?

我们将追溯到 "C" 并意识到我们想要包括的标签是 "A",但我们从未考虑过标签 "B",这将导致打包错误(假设除非 "B" 已经被选择)。

这个问题已在 Git 2.11(2016年第4季度)中得到修复。


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

请参见 commit be18153(2021年1月20日),由 Jacob Vosmaer(jacobvosmaer 提交。
(由Junio C Hamano -- gitster --commit 77db59c于2021年2月5日合并)

builtin/pack-objects.c:避免迭代所有引用

署名:Jacob Vosmaer
审核者:Taylor Blau

git-pack-objects中,如果在命令行上传递了--include-tag选项,则我们会遍历所有标签。
由于某种原因,这使用了for_each_ref,如果存储库有许多引用,则代价很高。
我们应该改用for_each_tag_ref
因为add_ref_tag回调现在只会访问标签,所以我们简化了它一点。
这个变化的动机是我们观察到一个在gitlab.com上有500,000个引用但只有2,000个标签的存储库存在性能问题。
该存储库的提取流量由CI主导,当我们将CI更改为使用 'git fetch --no-tags'(man) 进行提取时,我们看到了git-pack-objects的CPU配置文件中的显著变化。
这引导我们进行了这次特定的引用遍历。
更多细节请参见:https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/746#note_483546598

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接