【问题标题】:Can you tag individual folders/files in Git?你可以在 Git 中标记单个文件夹/文件吗?
【发布时间】:2020-06-23 16:23:10
【问题描述】:

我有一个名为“库”的存储库。这个 repo 包含我的项目的多个库文件(例如数学、显示等),它们彼此相对独立。当时,创建一个单独的 repo 似乎比为每个单独的库文件创建 repo 更容易。

但是,我现在遇到了标记这些文件的问题。在 Git 中进行标记基本上标记了整个 repo,这将给我留下一个 repo 库版本。但是,我有兴趣单独标记文件,以便其他项目可以引用特定版本(例如数学 1.0、显示 1.1 等)

将每个文件分解为自己的存储库的唯一解决方案是这样每个文件都可以用特定版本标记吗?但是,为每个文件创建一个 repo 似乎很浪费。

【问题讨论】:

  • 标记单个文件不是 Git 做事的方式......我真的不知道如何做你想做的事,除了让每个需要标签的单元都存在于自己的仓库中,我意识到这是你想要避免的。
  • 这能回答你的问题吗? Git tag for a subfolder of a repository

标签: git github tags


【解决方案1】:

TL;DR per TTT: you can, but you probably shouldn't. ?

Git 标签标识任何内部 Git 对象。

Git 中标记的正常用例是标记特定的commit,这当然是该提交中所有文件的完整快照,以及有关该提交的常用信息——谁做的,什么时候做的,等等,包括它的父母的哈希ID,即历史所需的一切。因此,标记提交标记了许多文件并提供了导致该提交的历史记录。

然而,Git 内部的对象是:

  • 标记对象本身(因此您可以标记标记对象——据我所知,这没有任何实际用途,但受支持);
  • 提交对象(通常情况);
  • tree 对象,代表一个充满文件的目录(包含在提交中);和
  • blob 对象,代表特定文件的特定版本。

因此,您可以标记一个特定文件的一个特定版本——例如,一个通过提交存储的树对象存储的 blob 对象——或一个包含文件的特定目录:

git tag lightweighttag HEAD:path/to/file.txt
git tag -a annotatedtag HEAD:path/to/

将创建两个这样的标签,指向当前提交中的一个文件和一个目录。这样做的主要问题是很少有其他 Git 工具真正了解如何处理这样的标签。 (作为LeGEC points out in a comment,您也无法从这里轻松找到任何历史记录:在 Git 存储库中,历史记录是 commits,而这些不是提交。)

如果一个名为math-1.0 的标签引用了一个包含文件的特定目录,那么您可能稍后只想将这些文件提取到某个工作区。为此,您可以使用git archive 对这些文件进行 zip 或 tar 归档:

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

例如。但这并不是特别方便,这意味着如果您发现了一个错误,您可能必须回到原始存储库来修复它。如果这些组件应该与其他任何东西分离,那么将它们放在单独的存储库中确实更有意义。

【讨论】:

  • 像往常一样,我从您的回答中学到了很多。和往常一样,这可能会受益于顶部的“tl;dr”。 ;) 我在想类似“tl;dr:你可以,但也许你不应该。”呵呵。
  • 我想明确地说:从技术上讲,您可以标记文件或目录,但您无法提取诸如“该对象的历史是什么?上次修改时间是什么时候”之类的信息?”哪个 git 只存储 commits (而不是单个文件或目录)
【解决方案2】:

对于您的用例:我会坚持标记提交。

查看我对另一个问题的回答:Monorepo Version Tags Conventions

如果你给你的标签命名:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    相关资源
    最近更新 更多