Preserving timestamps
Henryk Gerlach
hgerlach at gmx.de
Tue Aug 7 10:29:54 CDT 2007
> From: "Miguel Freitas" (miguel cpti cetuc puc-rio br)
> Subject: Preserving timestamps
> Before you fry me in boiling oil... :-)
> I did read the FAQ ("Why is the modification time of files not
> restored on checkout?") and recent messages on ml ("Maintaining
> modified dates of files"). but...
>
> I'm currently using hg to manage a FPGA project with Xilinx tools.
> Their IDE stores about all files, schematics and stuff in plain text,
> which is a very good thing to allow using hg.
>
> My question is, i know preserving mtimes is bad in general, but is it
> possible to implement this feature for a specific set of files in a
> repository?
Okay, I gave it a shot, just for the fun of it.
Try the follwing two scripts (and share your improvements)
==== save-timestamps:begin ====
#!/usr/bin/env python
"""
Setup
=====
1. put save-timestamps and restore-timestamps in your path.
2. set up a timestamp container in the base of your repository
% touch .timestamps
% hg add .timestamps
3. set the hooks, i.e. add the lines to your .hg/hgrc
[hooks]
precommit= hg status | ~/bin/save-timestamps
update=~/bin/restore-timestamps
4. optionally register all files from your manifest
% (for f in $(hg manifest); do echo "A $f"; done) | save-timestamps
Bugs and Issues
===============
- There may be problems with timezones.
- The script should treat ".timestamps" more carefully (i.e. atomic save).
- ".timestamps" should possibly be in a human readable format
- Files that just change the timestamp but not content are not registered
- Filenames with strange characters like "\n" will cause problems
- Does this script scale?
- Can you replace it with a standard Unix-tool?
"""
import sys, os.path, time, pickle
VERSION = 0
timeStampDict = {}
def get_atime(path):
# return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(os.path.getmtime(path))) #this for touch -d
return (os.path.getatime(path),os.path.getmtime(path),
time.strftime("%Y-%m-%d %H:%M:%S %Z",time.localtime(os.path.getatime(path))),
time.strftime("%Y-%m-%d %H:%M:%S %Z",time.localtime(os.path.getmtime(path))) )
def load_timeStampDict(filename=".timestamps"):
global timeStampDict, VERSION
try:
f = open(filename,'rb')
data = pickle.load(f)
if data[0] > VERSION:
print >>sys.stderr, "Don't know how to read VERSION=%s" % VERSION
raise
timeStampDict = data[1]
except:
print >>sys.stderr, "Could not open %s" % filename
timeStampDict = {}
def save_timeStampDict(filename=".timestamps"):
global timeStampDict, VERSION
f = open(filename,'wb')
pickle.dump((VERSION,timeStampDict),f)
def scan_hg_status():
global timeStampDict
for line in sys.stdin:
state = line[0]
filename = line[2:-1]
if state in ["M","A"]:
print "recording timestamp of %s" % filename
timeStampDict[filename]=get_atime(filename)
elif state in ["R"] and timeStampDict.has_key(filename):
del timeStampDict[filename]
elif state in ["?","!"]:
pass
else:
print "Unkown state!"
raise state
load_timeStampDict()
scan_hg_status()
save_timeStampDict()
==== save-timestamps:end ====
==== restore-timestamps:begin ====
#!/usr/bin/env python
import sys, os, time, pickle
VERSION = 0
timeStampDict = {}
def set_times(path,times):
" times =(atime, mtime) "
print "Restoring %s timestamp" % path
os.utime(path,times)
def load_timeStampDict(filename=".timestamps"):
global timeStampDict, VERSION
try:
f = open(filename,'rb')
data = pickle.load(f)
if data[0] > VERSION:
raise "Don't know how to read VERSION=%s" % VERSION
timeStampDict = data[1]
except:
print >>sys.stderr, "Could not open %s" % filename
timeStampDict = {}
load_timeStampDict()
for filename in timeStampDict.keys():
t=timeStampDict[filename]
set_times(filename,(t[0],t[1]))
==== restore-timestamps:end ====
Have fun,
Henryk
--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kanns mit allen: http://www.gmx.net/de/go/multimessenger
More information about the Mercurial
mailing list