一个仓库子文件夹的Git标签

15

我使用Git将一个SVN仓库导入,然后在仓库中创建了自己的项目作为子文件夹。

我使用Git-SVN来使用SVN仓库,我的工作流程如下:

  1. git commit -am "提交信息"
  2. git svn rebase
  3. git svn dcommit

现在我想使用git tag -a RC1 -m '发布候选版本1'来给我的项目打标签,但我只想让我的项目获取该标签。

我该怎么做?

4个回答

20

TL;DR版本

如果您知道树的SHA-1,可以标记特定的目录(也称为树),但这不经常发生,而且很难使用该标记做有用的事情。

详细回答

Git中的每个对象都有一个唯一的SHA-1。最常见的是SHA-1表示提交,但它们也可以表示blob(文件内容)和tree(目录结构和文件名/文件权限映射)。您可以在Git对象文档中了解相关信息。

例如,假设我在存储库中的特定目录中。我可以运行 git ls-tree HEAD 来获取路径中文件/目录的列表以及它们的SHA-1:

$git ls-tree HEAD
100644 blob ed76d466f5025ce88575770b07a65c49b281ca59    app.css
100644 blob ed58ee4a9be6f5b58e25e5b025b25e6d04549767    app.js
100644 blob e2bed82bd9554fdd89d982b37a8e0659fe82390a    controllers.js
040000 tree f888c44e16f7811ba69a245adf35c4303cb0d4e7    data
100644 blob d68aa862e4746fc9abd0132cc576a4df266b0a9d    directives.js
100644 blob df0ae0e7288617552b373d21f7796adb8fb0d1b6    index.html
040000 tree fa9c05b1bb45fb85821c7b1c27925b2618d646ac    partials
100644 blob 28e9eb6fe697cb5039d1cb093742e90b739ad6af    services.js

我可以标记其中一个树形结构(比如说上面的data目录):

$git tag data-1.0 f888c44e16f7811ba69a245adf35c4303cb0d4e7

该标签现在是该SHA-1的别名,我可以在任何需要树的SHA-1的地方使用它:
$git ls-tree -rt data-1.0
100644 blob 6ab0a52a17d14cbc8e30c4bf8d060c4ff58ff971    file1.json
100644 blob e097e393fa72007b0c328d67b70ba1c571854db0    file2.json
040000 tree 39573c56941fdd2fc88747a96bf871550f4affb2    subfolder1
...    ...  ...                                         ...

要获取原始的SHA-1:

$git rev-parse data-1.0
f888c44e16f7811ba69a245adf35c4303cb0d4e7

这些对你有什么好处?现在而言,作用不大。但是,如果你愿意编写自己的脚本来重建树的内容,或者找到包含树的提交,那么它可能对你有用。(例如,这个SO答案可以为此目的进行调整)。
但正如其他人所说,你可能会更容易地使用适合Git的版本控制/标记模型,而不是尝试适应现有模型。就像shikjohari和其他人已经提到的,如果你想要项目内的子项目,它们有自己的版本,请考虑使用Git子模块

1
巧妙的解决方案(虽然我实际上不想使用它 :-) )。 - sleske

7
你不能这样做。
在Git中,标签设计上总是适用于整个仓库(就像提交和分支一样)。这与Subversion不同,因为标签(只是复制)可以应用于子树。
顺便说一下:即使在Subversion中,标记子树通常也是不鼓励的,因为很快就会变得混乱,不知道哪部分是被标记的。我所知道的大多数来源(例如《Subversion版本控制》)都建议始终通过复制 trunk 来标记。
关于你的问题:
通常,单独的项目应该有单独的Git仓库。在这种情况下,“单独”通常意味着您可能希望分别进行分支/标记。
如果您不能或不想这样做,最好的选择可能是使用一些标签前缀,并将所有标签称为 myproj-1.0 myproj-1.1 等。

3
这是Git不可能实现的。Git标签是指向特定提交的指针,而Subversion标签则是Subversion存储库中任何文件夹的副本。在Subversion中对单个文件夹进行标记的概念并不能很好地转移到Git中。
问题在于您的初始设置与Git的分支模型不匹配。以Git友好的方式执行此操作的方法是设置项目的分支,然后在该分支上对提交进行标记。
您有几个选项:
- 使用git svn tag在给定点标记整个存储库。运行git help svn以获取有关使用此命令的说明。 - 使用常规的Subversion命令标记目录。这不需要下载Subversion工作副本,因为您只需运行svn copy {URL to your project on the repository} {URL to your tag directory},但您需要安装Subversion。 - 在全新的目录中开始Subversion存储库的新Git克隆。将您的项目文件夹指定为主干URL,而不是实际的主干。然后,Git-svn将将该目录视为您的主要分支,并允许您通过Subversion对其进行标记和复制。

1
我发现自己在将一个非常大的项目移动到Git时遇到了类似的问题。我发现团队没有正确处理SVN,并且从任何地方进行标记。因此,存在针对个别项目和文件夹的标记 - 这是极不鼓励的。
如果您计划转移到Git,您应该保持Git的工作方式并保持清洁。我建议创建经常更改的项目的单独存储库。如果您发现您的项目依赖于其他项目,则可以使用子模块。

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