你可以在Git中给单个文件夹/文件打标签吗?

4
我有一个名为“libraries”的存储库。这个存储库包含了多个项目中相对独立的库文件(例如:math、display等)。当时,创建单个存储库比为每个库文件创建存储库似乎更容易些。
但是,我现在遇到了标记这些文件的问题。Git 中的标记会将整个存储库打上标签,这将留下一个单独的存储库库版本。但是,我希望可以单独标记每个文件,以便其他项目可以引用特定版本(如:math 1.0、display 1.1 等)。
唯一的解决方案是将每个文件拆分为自己的存储库,以便每个文件都可以被标记为特定的版本吗?这种方式似乎有些浪费。

标记单个文件并不是Git的做事方式...我真的不知道如何做你想要的事情,除非让每个需要标记的单元都存在于自己的存储库中,但我意识到这正是你想避免的。 - joanis
这个回答解决了你的问题吗?Git 子文件夹的标签 - bain
2个回答

6

TL;DR per TTT: 可以,但最好不要。

Git标签用于标识Git内部对象。

在Git中使用标签的通常情况是对特定提交进行标记,这当然是该提交中所有文件的完整快照,以及有关提交的通常信息——谁做的,何时做的等等,包括其父代或祖先的哈希ID,即所有历史所需的内容。因此,标记提交标记了许多文件并提供了导致该提交的历史记录。

然而,在Git内部的对象是:

  • 标签对象本身(因此您可以标记一个标签对象-据我所知,这没有任何实际用途,但它是受支持的);
  • 提交对象(通常情况下);
  • 对象,它表示一个充满文件的目录(作为提交包含的部分);和
  • blob对象,表示特定文件的特定版本。
你因此可以标记一个特定版本的文件,例如通过树对象存储的Blob对象或提交存储的Blob对象,或者一个特定目录下的所有文件:
git tag lightweighttag HEAD:path/to/file.txt
git tag -a annotatedtag HEAD:path/to/

会创建两个这样的标签,指向当前提交中的一个文件和一个目录。 这样做的主要问题是很少有其他Git工具真正了解如何处理此类标签。(正如LeGEC在评论中指出的那样,您也很难从这里找到任何历史记录:在Git存储库中,历史记录是提交,而这些不是提交。)

如果名为math-1.0的标签引用了一个包含文件的特定目录,则您可能希望稍后将这些文件提取到某个工作区域中。 为此,您可以使用git archive制作这些文件的zip或tar归档:

git archive --format=tar math-1.0 | tar -C /path/to/dest -xf -

例如。但这并不特别方便,这意味着如果您发现一个错误,您可能需要返回到原始存储库进行修复。如果这些组件应该与其他任何东西解耦,那么将它们放在单独的存储库中更有意义。

像往常一样,我从你的回答中学到了很多。而且像往常一样,这篇文章在顶部加上一个“tl;dr”可能会更好。 ;) 我想要写上类似于“tl;dr:你可以,但也许你不应该。” 呵呵。 - TTT
我想明确表达:从技术上讲,您可以为文件或目录打标签,但是您将无法提取诸如“这个对象的历史记录是什么?最后修改时间是什么?”这样的信息,Git只会将其存储在提交中(而不是单独的文件或目录)。 - LeGEC

4

针对您的使用情况: 我建议您仍然使用标记提交。

请参考我的另一个回答:Monorepo版本标记约定

如果您给标记命名:

module1/1.0.0
module1/1.1.0
...
module2/1.0.0
module2/1.0.1
...

您可以轻松列出并排序针对单个模块的标签:
# list tags for module1 :
$ git tag --list 'module1/*'

# list tags and sort them as version numbers
# (e.g : display '1.10' after '1.9', not between '1.1' and '1.2') :
$ git tag --list 'module1/*' --sort="version:refname" 

如果标签的名称可以轻松映射存储库中目录的结构,您可以编写针对单个模块的代码和标签的命令。假设 module1 的代码位于 src/module1/module2 的代码位于 src/module2/business/module3 的代码位于 src/business/module3/ 等等... 您可以编写一个脚本(或函数)如下:
 # script git-logmodule :
 module=$1

 git log --decorate-refs=refs/tags/$module --decorate-refs=refs/heads -- src/$module

您可以获取特定模块的历史记录,仅用与该模块相关的标记进行修饰。

通过额外的脚本技巧,您可以向git log传递任何额外的选项。


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