Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: handling an appcache?

I'm hosting an OSS project on GitHub that has a few different developers. This project is a web application that is using an AppCache to tell the browser which files should be made available offline.

It's the nature of the appcache file that it needs to be updated (e.g. we are using a timestamp in a comment for that) once a file in the cache is changing to invalidate the cache and to force the browser to reload all files.
When people are working now on different development branches they are updating the timestamp in the appcache with each of their commits.

The problem is now, that this will create conflicts that are preventing an automatic merge.

  • How can this be solved in a way that not conflicts will happen again in the future?
  • What are other development teams doing at the same situation?

Using CVS I could replace the timestamp with a $Id$ to let the program handle it automatically...

like image 525
Chris Avatar asked Apr 26 '15 16:04

Chris


2 Answers

I have a large body of experience working with AppCache-backed applications served by a Rails stack.

I've found the easiest thing by far is to not hardcode your version into your AppCache. You should be generating the file dynamically, and programatically generating a unique value for the version. Ideally, nobody should be introducing change to the manifests themselves, they should be introducing change to the inputs that programatically generate the file.

This isn't really unique to the AppCache. If you find where one specific line needs to be modified in virtually every commit, you probably shouldn't be hard-coding that line. It should be generated in some way, based on whatever changes in the repo prompt a change to that line.

Returning to the AppCache, I've found the easiest thing to do is:

  • in development, include the last-modified time of all the files in the appcache
  • in production, include the commit ID of the deployed Git commit

I have no idea what language you're using, but in the Rails world, my AppCache manifest looked something like the following. Nobody would ever have to change this file, they would only add or remove files from the @files array, which is managed in the controller that serves up this manifest:

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:
*

The first part, wrapped in Rails.env.development? outputs a series of comment lines, containing the last-modified time of every file included in the manifest. This means that, during development, the AppCache will be automatically expired whenever any file included in it is modified.

In production, the AppCache was expired when a new commit was deployed. This might be overkill for you; if you want to avoid needlessly expiring the AppCache of your users, you should do something more clever like hashing the files involved so that the cache expires when their contents change.

In the end, I wound up writing a small library for helping eliminate the repetitive bits of generating manifests. On the off chance you are using Rails, you might find it helpful: https://github.com/meagar/rails_appcache

like image 54
meagar Avatar answered Oct 06 '22 12:10

meagar


Using CVS I could replace the timestamp with a $Id$ to let the program handle it automatically...

git can call git log's --format= handler on selected files when you're exporting code for deployment.

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 -
like image 25
jthill Avatar answered Oct 06 '22 11:10

jthill