[PATCH 1 of 1] Option to enforce using UTC for commit dates
arne_bab at web.de
arne_bab at web.de
Mon Dec 17 19:24:53 CST 2012
mercurial/cmdutil.py | 4 ++-
mercurial/commands.py | 5 +++-
mercurial/help/config.txt | 4 +++
mercurial/util.py | 51 ++++++++++++++++++++++++++++++++++++----------
tests/test-commit.t | 10 ++++++++-
5 Dateien verändert, 60 Zeilen hinzugefügt(+), 14 Zeilen entfernt(-)
# HG changeset patch
# User Arne Babenhauserheide <bab at draketo.de>
# Date 1355793798 -3600
# Node ID c4e74e535082cee18b73f09cf5b0c6b5ffbcd19d
# Parent 7aa7380691b8815200dda268aa1af19fd56aa741
Option to enforce using UTC for commit dates.
The timezone entries in commit messages give away location information
of the commiter, which can be dangerous when Mercurial is used
anonymously.
To mitigate that danger, this commit adds an rc-option to use UTC
dates, except when the timezone is requested explicitely via a date
string or by amending a commit without changing the date and time.
To switch to UTC times, add
[ui]
datetimeutc = True
to your ~/.hgrc or a .hg/hgrc.
Extensions like infocalypse can also set this option when doing the
initial clone from an anonymous source to ensure that the default
behaviour of Mercurial is safe.
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -1586,7 +1586,9 @@ def commit(ui, repo, commitfunc, pats, o
'''commit the specified files or all outstanding changes'''
date = opts.get('date')
if date:
- opts['date'] = util.parsedate(date)
+ opts['date'] = util.timezoneprivacy(ui.configbool('ui', 'datetimeutc'),
+ date)
+
message = logmessage(ui, opts)
# extract addremove carefully -- this function can be called from a command
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -1304,9 +1304,12 @@ def commit(ui, repo, *pats, **opts):
if not message:
message = old.description()
editor = cmdutil.commitforceeditor
+ date = util.timezoneprivacy(ui.configbool('ui', 'datetimeutc'),
+ opts.get('date'),
+ old.date())
return repo.commit(message,
opts.get('user') or old.user(),
- opts.get('date') or old.date(),
+ date,
match,
editor=editor,
extra=extra)
diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1128,6 +1128,10 @@ User interface controls.
changes, abort the commit.
Default is False.
+``datetimeutc``
+ Whether to always use Universal Time Coordinated (UTC) for date
+ entries when committing.
+
``debug``
Print debugging information. True or False. Default is False.
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -980,20 +980,20 @@ def shortdate(date=None):
"""turn (timestamp, tzoff) tuple into iso 8631 date."""
return datestr(date, format='%Y-%m-%d')
+def timezone(string):
+ tz = string.split()[-1]
+ if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit():
+ sign = (tz[0] == "+") and 1 or -1
+ hours = int(tz[1:3])
+ minutes = int(tz[3:5])
+ return -sign * (hours * 60 + minutes) * 60
+ if tz == "GMT" or tz == "UTC":
+ return 0
+ return None
+
def strdate(string, format, defaults=[]):
"""parse a localized time string and return a (unixtime, offset) tuple.
if the string cannot be parsed, ValueError is raised."""
- def timezone(string):
- tz = string.split()[-1]
- if tz[0] in "+-" and len(tz) == 5 and tz[1:].isdigit():
- sign = (tz[0] == "+") and 1 or -1
- hours = int(tz[1:3])
- minutes = int(tz[3:5])
- return -sign * (hours * 60 + minutes) * 60
- if tz == "GMT" or tz == "UTC":
- return 0
- return None
-
# NOTE: unixtime = localunixtime + offset
offset, date = timezone(string), string
if offset is not None:
@@ -1151,6 +1151,35 @@ def matchdate(date):
start, stop = lower(date), upper(date)
return lambda x: x >= start and x <= stop
+def timezoneprivacy(privacy, datestring=None, date=None):
+ """Switch to UTC if the timezone could be a risk to
+ privacy and the timezone was not requested explicitly.
+
+ >>> withtz = parsedate("2012-12-23 10:04:23 +0300")
+ >>> localtz = makedate()[1]
+ >>> notz = timezoneprivacy(True, "2012-12-23 07:04:23")
+ >>> notz[1] == 0
+ True
+ >>> notz[0] - localtz == withtz[0]
+ True
+ >>> (notz[0], localtz) == timezoneprivacy(False, "2012-12-23 07:04:23")
+ True
+ >>> (withtz[0], -3600) == timezoneprivacy(True, "2012-12-23 08:04:23 +0100")
+ True
+ >>> (withtz[0], 18000) == timezoneprivacy(True, "2012-12-23 02:04:23 -0500")
+ True
+ """
+ when = parsedate(datestring or date or makedate())
+ if not privacy:
+ return when
+ hastimezone = timezone(datestring) is not None
+ if datestring and not hastimezone:
+ return when[0], 0
+ if datestring or date:
+ return when
+ # no explicit datestring or date: use current UTC
+ return when[0], 0
+
def shortuser(user):
"""Return a short representation of a user name or email address."""
f = user.find('@')
diff --git a/tests/test-commit.t b/tests/test-commit.t
--- a/tests/test-commit.t
+++ b/tests/test-commit.t
@@ -90,12 +90,20 @@ commit added file that has been deleted
dir/file
committed changeset 4:49176991390e
-An empty date was interpreted as epoch origin
+date argument parsing
$ echo foo >> foo
$ hg commit -d '' -m commit-no-date
$ hg tip --template '{date|isodate}\n' | grep '1970'
[1]
+ $ echo foo >> foo
+ $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23' -m commit-utc
+ $ hg tip --template '{date|isodate}\n'
+ 1982-04-23 14:23 +0000
+ $ echo foo >> foo
+ $ hg --config ui.datetimeutc=True commit -d '1982-04-23 14:23 +0100' -m commit-utc
+ $ hg tip --template '{date|isodate}\n'
+ 1982-04-23 14:23 +0100
Make sure we do not obscure unknown requires file entries (issue2649)
More information about the Mercurial-devel
mailing list