Git中类似于Subversion的$URL$关键字扩展的等效方法

16

我正在考虑从Subversion迁移到Git。我们使用Subversion的一个用途是让系统管理员管理配置文件。为此,我们在每个文件中加入$URL$,它会扩展成该文件在Subversion树中的位置。这让管理员可以查看某个任意主机上的文件,并找到它来自树的哪个位置。

最接近的类比可能是gitattributes。有filter=指令,但似乎Git不会将过滤器正在过滤的文件名传递给过滤器,这对于将$URL$转换为路径是必要的。

还有ident指令,可以将$Id$转换为blob哈希值。如果能将其映射回路径名,则此选项可能可用,但我的Git知识不够强。

有什么建议吗?

工作流程如下:

  1. 管理员提交更改到VCS仓库
  2. 管理员更新已经检出仓库的中心位置
  3. 管理员使用cfengine将更改拉到主机上

当你说路径时,它主要用于识别分支还是分支内的实际路径? - Igor Zevaka
我的意思是文件的路径名。所以,如果管理员查看文件/etc/apache2/sites-available/trac,他将看到可以在VCS中找到该文件为https://eng.svn.pdaverticals.com/trunk/net/http/apache2/sites/trac。否则,他必须进行查找并希望文件名匹配,这可能不会发生,因为有些文件在发送到主机时会更改名称,有些文件由一堆不同的文件片段组成,甚至没有类似于VCS的模拟文件。 - Rudedog
4个回答

6
如在"Does git have anything like svn propset svn:keywords or pre-/post-commit hooks?"中提到的,Git不支持关键词扩展。
"使用基于git config filter(不是您想要的)和/或gitattributes的解决方案来处理使用GIT-SVN进行SVN关键字扩展。"。
我找到的最接近文件信息扩展的例子仍然基于印迹/清洁方法,使用这个git Hash过滤器,但是清洗部分会将其从文件中删除,并且无法找到路径。 此线程实际上详细说明了它(以及提到一些可能包含您要查找的内容的git-fu命令,我尚未对其进行测试):

无论如何,印迹/清洁不能立即解决问题,因为存在一些较小的技术缺陷:

  • 印迹过滤器未传递要检出的文件的名称,因此无法准确找到提交标识符。
    但是,由于“印迹”仅在更改的文件上运行,因此最后一次提交就是所需的。

  • 印迹过滤器未传递提交标识符。这有点更严重,因为此信息无处获取。
    我尝试使用“HEAD”值,但显然在“smudge”运行时尚未更新,因此文件的日期为“先前”提交而不是正在检出的提交。
    “先前”表示之前检出的提交。如果检出不同的分支,则问题会变得更糟,因为文件会获得以前分支的时间戳。

AFAIR,在污点/清洗机制中缺少信息是故意的,以防止这种特定的使用。但是,我认为可以重新考虑这种情况,考虑到彼得的用例:“仅检出”工作区,用于立即发布到Web服务器。
或者,任何对此用例感兴趣的人都可以实现其他弄脏参数作为站点本地补丁。

然后,还有一些小烦恼似乎是不可避免的:如果更改“清洗”过滤器并检出早期版本,则会报告为具有修改(由于更改了“清洗”定义)。


我已经阅读并排除了前两个链接,因为它们都没有我需要的功能。我也知道gitattributes,我认为在我的帖子中提到了这一点。 - Rudedog

4

现在有 %f 选项,像git-rcs-keywords这样的脚本可以完成任务。

这在这个答案中已经提到了。

gitattributes(5)手册页

Sequence "%f" on the filter command line is replaced with
the name of the file the filter is working on. A filter 
might use this in keyword substitution. For example:

[filter "p4"]
    clean = git-p4-filter --clean %f
    smudge = git-p4-filter --smudge %f

现在,git filter应该启动更多的git命令,希望提取一些git已经拥有的信息(而且无法提取提交哈希),这真正加快了事情的进展...这并不比post-checkout钩子更好 :-( - Arioch 'The

2

从完全不同的角度来看待这个问题,那么这些文件是如何出现在最终主机上的呢?我猜今天要么直接在那里签出,要么从另一个主机上已经签出的存储库中复制过来?

如果是这样,您可以修改您的流程,使文件被签出到git存储库,并且脚本在签出之后执行$URL$或其他关键字扩展。这样,您就可以进行任何所需的替换,只受签出存储库中的脚本能够解决的限制。


+1。更接近我所知道的生产环境:您不希望在终端主机上安装任何VCS工具。中间环境更加安全。 - VonC
1
我们确实有一个主管理服务器,它具有版本控制系统的只读检出。我考虑过在检出后进行编辑,但问题是git会认为所有文件都已被修改,随后的git pull将失败。我还考虑过使用git-archive刷新中央暂存区,但这会导致文件时间戳等方面的各种问题。 - Rudedog
1
我同意,这不是最优解。通过执行类似于 git reset --hard; git pull; do-substitutions; deploy-files 的操作可能会起作用,但仍然不完全符合您的要求。 :) - Jakob Borg

1

我们在部署中使用“规范路径”解决方案(它们都是内部的,顺便说一下)。

所有软件都放在例如/d/sw/xyz/a.cD:\SW\xyz\a.c中。

所有指向已部署文件的URL都反映了这一点,例如http://host/d/sw/xyz/a.c

指向存储库文件的URL从“sw”开始,例如git://githost/gitrepo/xyz/a.c

我们在配置中编码这些规范路径(如果需要更改),并且我们有脚本/API可以动态生成/引用URL以在组件之间进行动态链接。


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