【问题标题】:Labeling / Marking a group of files in Git在 Git 中标记/标记一组文件
【发布时间】:2017-01-04 05:37:46
【问题描述】:

有没有办法在 Git 中用标签逻辑地标记一组文件? 我了解标签和 Gitlab 标签的工作原理,但是……在这两种情况下,这些标记都应用于提交。

我们使用的应用程序 ETL 使用特定的目录树,在识别 3 个文件属于解决方案 X 和其他 2 个文件(在同一目录中)属于解决方案 Y 时,该目录树不太灵活。

标记/标记文件的子集,而不是将它们放置在特定于功能的文件夹中或按照命名约定进行编码...将使它们更容易识别。
顺便说一句,这些文件是 XML(ETL 作业)或平面文件(SQL/DDL)。

你会怎么做?

【问题讨论】:

  • Git 本质上是一个基于提交的 VCS 工具。即使您可以以这种方式标记文件,您将如何在实践中使用它?
  • 嗨@TimBiegeleisen,基本上,这是识别用于同一应用程序/模块的所有文件。我想快速识别模块(这反过来将允许我们将测试套件链接到“应用程序”,而不是真正的低级对象,如表或视图)。不幸的是,我们使用的工具并没有提供一种方法来创建包,例如您在 Java 中所做的那样......

标签: git labels tagging


【解决方案1】:

由于每次要应用标签时将这些文件分组在一个提交中是不切实际的,因此您至少可以考虑给您留个便条,提醒您哪些文件属于哪个解决方案。

请参阅git notes:这将是一个由您管理的文本注释,列出了给定解决方案要考虑的文件。
对于给定的提交,您可以附加多个注释。

这是一种解决方法,以考虑到 Git 本身基于提交将无法标记文件的事实。

【讨论】:

  • @TimBiegeleisen 谢谢蒂姆。也祝你好运。
【解决方案2】:

正如其他人所说,没有内置的东西可以做到这一点。然而,我们可能会注意到,Git 在存储库本身中存储了四种对象:blob(文件)、树(表示满目录的文件)、提交(通过 parent 形成有向无环图em> 标识符,每个提交携带一个 tree 对象、一个作者、一个提交者、它的父集和任意日志消息)和注释标签对象(没有强定义关系,但每个标签只有一个目标对象,通常是一个提交)。

旁白:git notes 的工作原理

Git 的 notes 在内部表示为提交。每个提交都有一组“文件”作为它的树,它们的名称只是碰巧——完全是偶然的:-) ...咳咳——与某些提交集完全相同1在存储库中。当git log 显示一个ID 为C 的提交时,它“偶然”检查refs/notes/commits 是否存在,如果存在,是否存在名为C 的文件存在于refs/notes/commits 指向的提交中,如果存在,则将该文件的内容附加到日志消息中。所以这就是注释附加到提交的方式:Git 的一个内置部分检查是否有特殊引用 (refs/notes/commits) 指向包含包含“文件”的树的提交(最终它确实是一个文件,因为它是一个普通的 Git blob 对象),应该添加到提交日志消息中。

当您修改注释集时,Git 只需使用新树进行新提交。新的提交指向之前的 refs/notes/commits 提交作为其父提交,因此旧的注释仍然存在并且可以(有一些困难)被视为过去(这曾经非常困难;我相信它变得更容易了)。 Git 的自然压缩包文件可以很好地处理这些问题,因此笔记占用的空间只会随着新笔记的添加而线性增长。


1为了提高效率,对“名称”进行了一些修改,例如,可以将注释文件命名为deadbeefcafebabec0ffeedecadefadedbedcede,而不是命名为de/ad/beefcafe...


因此,解决方案是显而易见的(咳咳)

您希望表示排列在一个目录或一系列目录中的一组文件。那当然是一棵,而Git 有树对象。因此,您应该创建一个树对象来保存其中一种状态。

你没有说你是否希望保留这棵树的多个历史版本。如果这样做,解决方案很明显:就像git notes 一样处理它们,使用新的提交对象来存储每个新树,链接提交以使过去的版本可检索。如果没有,是否创建提交对象完全取决于您,因为单个标签对象可以直接指向树对象。 (一些非 Git 工具可能在提交或其他标签之外的任何标签上存在问题。不过,Git 本身的 Git 存储库中有一些这样的标签。)

无论如何,您还需要一个顶级引用来指向指向最新树的提交或注释标记对象。

创建树很容易:只需填充一个索引文件(不是常规文件,而是备用文件,您将其名称写入环境变量GIT_INDEX_FILE),使用您希望它们出现在树中的文件名,通过git add-ing 文件(如果它们不存在,这也会将必要的 blob 放入存储库中),然后调用 git write-tree。这会将索引转换为所需的树对象(之后您可能并且可能应该丢弃导出的 GIT_INDEX_FILE 设置),像往常一样将新对象的 ID 打印到标准输出。编写提交和/或标记对象以指向该树只需调用git commit-tree 和/或git mktag(它们会将自己的新对象写入存储库,像以前一样将ID 打印到标准输出) .最后,使用git update-ref 创建或更新指向标记或提交对象的引用——您现在已经重新实现了git notes,但形式更适合您自己的需求。

您可以随时将任何保存的树提取到您选择的任何工作树中,只需一个简单的git checkout 使用另一个临时索引。

【讨论】:

  • 所以... git notes,正如我所说的 ;) +1
【解决方案3】:

您是否要单独跟踪它们?如果是这样,我想知道您是否可以使用两个不同的本地 git repo 来实现这一点。看看this 的回答,看看如何在同一个目录中管理两个不同的 git repo。

否则,如果您只是需要一种在文件系统上标记文件的方法,那么 git 将无济于事。如何在各自的解决方案中包含两个文件.sol1.sol2 列出文件,然后为您的 git 操作编写一个小脚本。例如当你做git status -sol1时,它会首先对整个目录做git status,然后通过.sol中的文件过滤掉它等等。编写这样的脚本应该不难,而且我认为它在其他情况下也可能有用。如果您需要帮助,请告诉我。

【讨论】:

  • "嗨@yelsayed,感谢您的回复。它是一个包含 ETL 和 DDL 文件的数据仓库的存储库。整个 repo 代表 DW,但在 DW 中您有不同的应用程序,例如“” “采购分析”、“财务分析”等。我正在尝试找到一种方法来识别“财务分析由这 20 个文件组成(分散在文件夹中)”。目前有点乏味......当然,有些文件用于 2 个不同的应用程序!所以......多个标签会很有效!描述有点仓促,但......我希望我能阐明目标。”
  • 我认为列出 .sol1.sol2 文件中的文件应该可以工作。一个文件可以在两者中列出,因此它将显示在您的 git 命令中,依此类推。这能解决你的情况还是我错过了什么?
【解决方案4】:

Git 没有自然的方法来实现这一点,因为它真的只关心它被指示监视的文件中的更改。

对此的解决方案,尽管是大杂烩,将使用提交标签来引用处于特定状态的项目。同样,Git 不关心单个文件,甚至不关心它们是否相关。建立这种关系是你的责任。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多