Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Update both asset mtime and atime with touch #368

merged 1 commit into from

10 participants


We use multiple users with common group permissions to deploy. Since touch uses the utime library, a user can't set the mtime of a file even if they have write permissions unless they are the owner of the file. Since many production systems mount the file system with noatime anyways for performance, my suggestion is we update both atime and mtime on assets so that deploying with group write permissions still works.

This issue came to light in 2.14.0 with commit 8412ccf, because the touch command is no longer run silently. It was silently failing before but is not preventing a successful deployment.

This issue seems to be related: #352


I've been having this issue as well... apparently you can't change the mtime of a file without also changing the atime unless you're the owner of the file or root.




+1 was going to submit this exact same change.

/tmp/test1-> id
uid=1000(plyons) gid=1000(plyons) groups=1000(plyons),4(adm),20(dialout),24(cdrom),46(plugdev),109(lpadmin),110(sambashare),111(admin),1002(webadmin)
/tmp/test1-> ls --full-time
total 4
-r--rw---- 1 www-data webadmin 12 2013-02-17 11:50:05.366446594 -0700 test1
/tmp/test1-> touch -cm test1
touch: setting times of `test1': Operation not permitted
/tmp/test1-> ls --full-time 
total 4
-r--rw---- 1 www-data webadmin 12 2013-02-17 11:50:05.366446594 -0700 test1
/tmp/test1-> touch -c test1
/tmp/test1-> ls --full-time
total 4
-r--rw---- 1 www-data webadmin 12 2013-02-17 11:50:55.706845342 -0700 test1




This is a problem for me too.


This change helped me with my project. +1




I wasn't aware that mtime and atime were so wildly differently interpreted, but happy to merge this in my ignorance as it seems that it'll fix some issues for a bunch of you!

@leehambley leehambley merged commit b6400ca into capistrano:master

1 check failed

Details default The Travis build could not complete due to an error

@leehambley When is the next gem going out with this change?


@jgyllen when we resolve a couple of issues that have been merged, but caused some controversy. In the meantime, there's nothing serious stopping you from pointing your Gemfile at master, it's pretty stable. The big outstanding two weirdnesses are around the asset pipeline.


+1 we have this problem as well, I'll try using master.


These days I always disable asset timestamping entirely. Here's why:

For 90% of apps, which are on just a single server, touching assets is useless. It takes time and busts cache for no reason at all. At a minimum Capistrano should only touch assets when deploying to multiple servers.

For the other 10% which are on multiple servers, I have never deployed assets to multiple actual servers simultaneously. And I have deployed quite a few apps. In these cases the assets are on NFS that all front-end boxes see. Also making asset touching useless (and even slower).

I don't even know anyone who actually deploys assets to separate machines any more.


@tilsammans that's a good point. Overriding that function might be the best solution for us, we're only on a single server at this point. Thanks for the insight.


As seen elsewhere, here's what we implemented:

# override to disable touch -cm 
# See
# See
namespace :deploy do
  namespace :assets do
    task :update_asset_mtimes do ; end
@nettan20 nettan20 referenced this pull request from a commit in nettan20/job-board
@voikya voikya Temporarily ignoring capistrano update_asset_mtimes action due to gro…
…up permissions bug (capistrano/capistrano#368)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 29, 2013
  1. Update both asset mtime and atime with touch

    Jan Ulrich committed
This page is out of date. Refresh to see the latest.
Showing with 1 addition and 1 deletion.
  1. +1 −1  lib/capistrano/recipes/deploy/assets.rb
2  lib/capistrano/recipes/deploy/assets.rb
@@ -66,7 +66,7 @@
put{|a| "#{shared_path}/assets/#{a}" }.join("\n"), "#{deploy_to}/TOUCH_ASSETS"
run <<-CMD.compact
cat #{deploy_to.shellescape}/TOUCH_ASSETS | while read asset; do
- touch -cm -- "$asset";
+ touch -c -- "$asset";
done &&
rm -f -- #{deploy_to.shellescape}/TOUCH_ASSETS
Something went wrong with that request. Please try again.