Git:如何处理应用程序缓存?

15
我在GitHub上托管了一个开源项目,有几个不同的开发者参与。这个项目是一个Web应用程序,使用AppCache告诉浏览器哪些文件可以脱机使用。
AppCache的特性是需要更新它的文件(例如,在注释中使用时间戳)以使缓存失效并强制浏览器重新加载所有文件。
现在,当人们在不同的开发分支上工作时,他们都会在每次提交时更新appcache中的时间戳。
问题是,这将创建冲突,从而阻止自动合并。
  • 如何以避免未来再次发生冲突的方式解决此问题?
  • 其他开发团队在相同情况下做了什么?
使用CVS,我可以用$Id$替换时间戳,让程序自动处理...

问题是通用的,也应该通用地回答。但是为了提供信息:在我的情况下,应用程序仅使用静态JavaScript、CSS和HTML文件,因此一个非常简单的Web服务器就足够了。一些可选部分使用PHP - 但这不是运行时环境的硬性要求(但我猜开发Web服务器100%都有它)。如果有一个解决方案,Git应该调用一个脚本,应该考虑到开发人员正在使用Linux、Windows和MacOS。 - Chris
3个回答

7

我在使用Rails技术栈为基础的AppCache应用程序方面拥有丰富的经验。

从远见角度来看,将版本信息硬编码到AppCache中是最简单的方法,但实际上不推荐这样做。你应该动态生成文件,并以编程方式生成唯一版本值。理想情况下,没有人应该直接修改清单文件本身,而应该通过修改程序化生成文件的输入来引入更改。

这个问题并不仅仅适用于AppCache。如果你发现需要在几乎每次提交时修改某个特定行,那么最好不要将其硬编码。应该以某种方式生成它,该方式基于对库所做更改会提示修改该行的内容。

回到AppCache,我发现最简单的方法是:

  • 开发环境中,包括所有文件的最后修改时间
  • 生产环境中,包括部署的Git提交的commit ID

我不知道你使用的是哪种语言,但在Rails世界中,我的AppCache清单文件类似于以下内容。没有人需要直接修改此文件,他们只需要向@files数组添加或删除文件,该数组由提供此清单的控制器管理:

CACHE MANIFEST

<% if Rails.env.development? %>
<% @cached_files.each do |file| %>
# <%= File.mtime(file) %>
<% end %>
<% else %>
# <%= `git rev-parse HEAD` %>
<% end %>

CACHE:
<% @cached_files.each do |file| %>
<%= file %>
<% end %>

NETWORK:
*

第一部分被包含在内的内容输出了一系列注释行,包含清单中每个文件的最后修改时间。这意味着,在开发过程中,只要任何一个包含在清单中的文件被修改,AppCache就会自动过期。
在生产环境中,当部署新提交时,AppCache会过期。这可能对你来说有些过度了;如果你想避免不必要地使用户的AppCache过期,你应该做一些更聪明的事情,比如对涉及的文件进行哈希处理,这样当它们的内容发生变化时,缓存就会过期。
最终,我写了一个小库来帮助消除生成清单中重复的部分。如果你碰巧正在使用Rails,你可能会觉得它很有用:https://github.com/meagar/rails_appcache

1

使用CVS,我可以将时间戳替换为$Id$,让程序自动处理...

当您导出代码进行部署时,git可以在选定的文件上调用git log--format=处理程序

echo \*.meta  export-subst   >>.gitattributes

echo   '$Format:%cD$'   >test.meta   # there's lots of % codes available.
git add .; git commit -m-; 

git archive v2.3.6 | tar xCf /dir/that/appcache/is/watching -

1
为了在普通的Git checkout中模拟CVS关键字扩展,你可以使用Git中的clean/smudge过滤器,如此处所述:关键字扩展
另一个选择是继续按照您目前的方式进行,但定义一个自定义合并驱动程序,该驱动程序将在合并之前删除时间戳,执行合并本身,然后重新添加新的时间戳。

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