Changeset 1216 in tailor
- Timestamp:
- 07/06/06 17:29:20 (7 years ago)
- Hash name:
- 20060706152920-d6905-8960cdcccc5a3f12129b7cc60291cb58c183d98b
- Location:
- vcpx
- Files:
-
- 1 added
- 16 edited
-
changes.py (modified) (1 diff)
-
repository/cvsps.py (modified) (3 diffs)
-
repository/darcs.py (modified) (4 diffs)
-
repository/svn.py (modified) (3 diffs)
-
tests/cvsps.py (modified) (2 diffs)
-
repository/cvs.py (modified) (6 diffs)
-
tests/cvs.py (modified) (15 diffs)
-
tests/darcs.py (modified) (4 diffs)
-
tests/svn.py (modified) (8 diffs)
-
repository/monotone.py (modified) (3 diffs)
-
repository/cdv.py (modified) (2 diffs)
-
repository/tla.py (modified) (3 diffs)
-
repository/bzr.py (modified) (5 diffs)
-
repository/cg.py (modified) (1 diff)
-
repository/git/target.py (modified) (3 diffs)
-
repository/hg.py (modified) (4 diffs)
-
tzinfo.py (added)
Legend:
- Unmodified
- Added
- Removed
-
vcpx/changes.py
r1162 r1216 100 100 REFILL_MESSAGE = False 101 101 """Refill changelogs""" 102 103 def _get_date(self): 104 return self.__date 105 106 def _set_date(self, date): 107 if date and date.tzinfo is None: 108 raise "Tailor bug (please report): Changeset dates must have a timezone." 109 self.__date = date 110 111 # date has to be a property because some backends (eg. monotone) 112 # update it after the constructor 113 date = property(_get_date, _set_date) 102 114 103 115 def __init__(self, revision, date, author, log, entries=None, **other): -
vcpx/repository/cvsps.py
r1215 r1216 20 20 InvocationError 21 21 from vcpx.target import SynchronizableTargetWorkingDir, TargetInitializationFailure 22 from vcpx.tzinfo import UTC 22 23 23 24 … … 208 209 y,m,d = map(int, cvsdate[:10].split('/')) 209 210 hh,mm,ss = map(int, cvsdate[11:19].split(':')) 210 timestamp = datetime(y, m, d, hh, mm, ss )211 timestamp = datetime(y, m, d, hh, mm, ss, 0, UTC) 211 212 pset['date'] = timestamp 212 213 … … 403 404 if timestamp == 'INITIAL': 404 405 initialcset = csets.next() 405 timestamp = initialcset.date. isoformat(sep=' ')406 timestamp = initialcset.date.replace(tzinfo=None).isoformat(sep=' ') 406 407 else: 407 408 initialcset = None -
vcpx/repository/darcs.py
r1215 r1216 19 19 GetUpstreamChangesetsFailure 20 20 from vcpx.target import SynchronizableTargetWorkingDir, TargetInitializationFailure 21 from vcpx.tzinfo import UTC 21 22 22 23 … … 146 147 # Old darcs patches use the form Sun Oct 20 20:01:05 EDT 2002 147 148 timestamp = datetime(*strptime(date[:19] + date[-5:], '%a %b %d %H:%M:%S %Y')[:6]) 149 150 timestamp = timestamp.replace(tzinfo=UTC) # not true for the ValueError case, but oh well 151 148 152 self.current['date'] = timestamp 149 153 self.current['comment'] = '' … … 308 312 author = l[30:-1] 309 313 y,m,d,hh,mm,ss,d1,d2,d3 = strptime(date, "%a %b %d %H:%M:%S %Z %Y") 310 date = datetime(y,m,d,hh,mm,ss )314 date = datetime(y,m,d,hh,mm,ss,0,UTC) 311 315 l = output.readline() 312 316 assert (l.startswith(' * ') or … … 550 554 logmessage = [] 551 555 552 logmessage.append(date. strftime('%Y/%m/%d %H:%M:%S UTC'))556 logmessage.append(date.astimezone(UTC).strftime('%Y/%m/%d %H:%M:%S UTC')) 553 557 logmessage.append(author) 554 558 if patchname: -
vcpx/repository/svn.py
r1215 r1216 17 17 from vcpx.target import SynchronizableTargetWorkingDir, TargetInitializationFailure 18 18 from vcpx.config import ConfigurationError 19 from vcpx.tzinfo import UTC 19 20 20 21 … … 259 260 hh,mm,ss = map(int, svndate[11:19].split(':')) 260 261 ms = int(svndate[20:-1]) 261 timestamp = datetime(y, m, d, hh, mm, ss, ms )262 timestamp = datetime(y, m, d, hh, mm, ss, ms, UTC) 262 263 263 264 changeset = Changeset(self.current['revision'], … … 580 581 propset = ExternalCommand(cwd=self.repository.basedir, command=cmd) 581 582 583 date = date.astimezone(UTC).replace(microsecond = 0, tzinfo=None) 582 584 propset.execute(date.isoformat()+".000000Z", propname='svn:date') 583 585 propset.execute(encode(author), propname='svn:author') -
vcpx/tests/cvsps.py
r1179 r1216 9 9 from datetime import datetime 10 10 from vcpx.repository.cvsps import changesets_from_cvsps 11 from vcpx.tzinfo import UTC 11 12 12 13 … … 30 31 self.assertEqual(cset.revision, '1500') 31 32 self.assertEqual(cset.author, "grubert") 32 self.assertEqual(cset.date, datetime(2004, 5, 9, 17, 54, 22 ))33 self.assertEqual(cset.date, datetime(2004, 5, 9, 17, 54, 22, 0, UTC)) 33 34 self.assertEqual(cset.log, "Tell the reason for using mbox " 34 35 "(not wrapping long lines).") -
vcpx/repository/cvs.py
r1215 r1216 16 16 from vcpx.source import GetUpstreamChangesetsFailure 17 17 from vcpx.config import ConfigurationError 18 from vcpx.tzinfo import UTC 18 19 19 20 … … 152 153 """ 153 154 154 return "%s by %s" % (timestamp, author) 155 # don't print timezone info, to remain compatible (does not buy us 156 # anything, it being always UTC) 157 return "%s by %s" % (timestamp.replace(tzinfo=None), author) 155 158 156 159 def _splitGlobalCVSRevision(revision): … … 285 288 y,m,d = map(int, day.split(day[4])) 286 289 hh,mm,ss = map(int, time.split(':')) 287 date = datetime(y,m,d,hh,mm,ss )290 date = datetime(y,m,d,hh,mm,ss,0,UTC) 288 291 289 292 assert info[1].strip()[:8] == 'author: ', infoline … … 469 472 # probably get a better date by looking at when the 470 473 # files were added, but who cares. 471 timestamp = datetime(1900,1,1) 474 timestamp = datetime(1900,1,1).replace(tzinfo=UTC) 472 475 else: 473 476 # "since" is a revision name read from the state file, … … 477 480 # call to timestamp.__str__() in getGlobalCVSRevision. 478 481 y,m,d,hh,mm,ss,d1,d2,d3 = strptime(since, "%Y-%m-%d %H:%M:%S") 479 timestamp = datetime(y,m,d,hh,mm,ss )482 timestamp = datetime(y,m,d,hh,mm,ss,0,UTC) 480 483 author = "unknown tagger" 481 484 changelog = "tag %s %s" % (timestamp, tags) … … 668 671 669 672 if ts == 'Result of merge': 670 self.timestamp = datetime. today()673 self.timestamp = datetime.now(tz=UTC) 671 674 else: 672 675 if ts.startswith('Result of merge+'): 673 676 ts = ts[16:] 674 677 y,m,d,hh,mm,ss,d1,d2,d3 = strptime(ts, "%a %b %d %H:%M:%S %Y") 675 self.timestamp = datetime(y,m,d,hh,mm,ss )678 self.timestamp = datetime(y,m,d,hh,mm,ss,0,UTC) 676 679 677 680 self.cvs_tag = tag -
vcpx/tests/cvs.py
r1183 r1216 11 11 from vcpx.repository.cvs import changesets_from_cvslog, compare_cvs_revs, \ 12 12 cvs_revs_same_branch, normalize_cvs_rev 13 from vcpx.tzinfo import UTC 13 14 14 15 … … 26 27 self.assertEqual(e.filename, 'version.txt') 27 28 self.assertEqual(e.cvs_version, '1.16.2.1') 28 self.assertEqual(e.timestamp, datetime(2004, 7, 13, 12, 49, 2 ))29 self.assertEqual(e.timestamp, datetime(2004, 7, 13, 12, 49, 2, 0, UTC)) 29 30 self.assertEqual(e.cvs_tag, 'T1.16.2.1') 30 31 … … 33 34 self.assertEqual(e.filename, 'Validator.py') 34 35 self.assertEqual(e.cvs_version, '1.31.2.5') 35 self.assertEqual(e.timestamp, datetime(2004, 7, 13, 13, 43, 6 ))36 self.assertEqual(e.timestamp, datetime(2004, 7, 13, 13, 43, 6, 0, UTC)) 36 37 self.assertEqual(e.cvs_tag, 'T1.31.2.5') 37 38 … … 40 41 self.assertEqual(e.filename, 'Makefile.am') 41 42 self.assertEqual(e.cvs_version, '1.55') 42 self.assert_((datetime. today() - e.timestamp) < timedelta(seconds=1))43 self.assert_((datetime.now(tz=UTC) - e.timestamp) < timedelta(seconds=1)) 43 44 self.assertEqual(e.cvs_tag, 'T1.55') 44 45 … … 64 65 cset = csets[0] 65 66 self.assertEqual(cset.author, "goodger") 66 self.assertEqual(cset.date, datetime(2004, 6, 3, 13, 50, 58 ))67 self.assertEqual(cset.date, datetime(2004, 6, 3, 13, 50, 58, 0, UTC)) 67 68 self.assertEqual(cset.log, "Added to project (exctracted from " 68 69 "HISTORY.txt)") … … 74 75 cset = csets[1] 75 76 self.assertEqual(cset.author, "goodger") 76 self.assertEqual(cset.date, datetime(2004, 6, 10, 2, 17, 20 ))77 self.assertEqual(cset.date, datetime(2004, 6, 10, 2, 17, 20, 0, UTC)) 77 78 self.assertEqual(cset.log, "") 78 79 entry = cset.entries[0] … … 89 90 cset = csets.next() 90 91 self.assertEqual(cset.author, "goodger") 91 self.assertEqual(cset.date, datetime(2004, 4, 27, 19, 51, 07 ))92 93 cset = csets.next() 94 self.assertEqual(cset.author, "goodger") 95 self.assertEqual(cset.date, datetime(2004, 6, 17, 2, 8, 48 ))96 97 cset = csets.next() 98 self.assertEqual(cset.author, "goodger") 99 self.assertEqual(cset.date, datetime(2004, 6, 17, 2, 51, 31 ))100 101 cset = csets.next() 102 self.assertEqual(cset.author, "goodger") 103 self.assertEqual(cset.date, datetime(2004, 6, 17, 21, 46, 50 ))92 self.assertEqual(cset.date, datetime(2004, 4, 27, 19, 51, 07, 0, UTC)) 93 94 cset = csets.next() 95 self.assertEqual(cset.author, "goodger") 96 self.assertEqual(cset.date, datetime(2004, 6, 17, 2, 8, 48, 0, UTC)) 97 98 cset = csets.next() 99 self.assertEqual(cset.author, "goodger") 100 self.assertEqual(cset.date, datetime(2004, 6, 17, 2, 51, 31, 0, UTC)) 101 102 cset = csets.next() 103 self.assertEqual(cset.author, "goodger") 104 self.assertEqual(cset.date, datetime(2004, 6, 17, 21, 46, 50, 0, UTC)) 104 105 self.assertEqual(cset.log,"support for CSV directive implementation") 105 106 self.assertEqual(len(cset.entries), 2) … … 115 116 cset = csets.next() 116 117 self.assertEqual(cset.author, "felixwiemann") 117 self.assertEqual(cset.date, datetime(2004, 6, 20, 16, 3, 17 ))118 self.assertEqual(cset.date, datetime(2004, 6, 20, 16, 3, 17, 0, UTC)) 118 119 119 120 def testDeletedEntry(self): … … 144 145 cset = csets[0] 145 146 self.assertEqual(len(cset.entries), 2) 146 self.assertEqual(cset.date, datetime(1996, 10, 7, 18, 32, 12 ))147 self.assertEqual(cset.date, datetime(1996, 10, 7, 18, 32, 12, 0, UTC)) 147 148 148 149 cset = csets[1] 149 150 self.assertEqual(len(cset.entries), 1) 150 self.assertEqual(cset.date, datetime(1996, 10, 14, 13, 56, 50 ))151 self.assertEqual(cset.date, datetime(1996, 10, 14, 13, 56, 50, 0, UTC)) 151 152 entry = cset.entries[0] 152 153 self.assertEqual(entry.name, 'Doc/libObjCStreams.tex') … … 154 155 cset = csets[2] 155 156 self.assertEqual(len(cset.entries), 1) 156 self.assertEqual(cset.date, datetime(1996, 10, 18, 12, 36, 4 ))157 self.assertEqual(cset.date, datetime(1996, 10, 18, 12, 36, 4, 0, UTC)) 157 158 entry = cset.entries[0] 158 159 self.assertEqual(entry.name, 'Doc/libPyObjC.tex') … … 160 161 cset = csets[3] 161 162 self.assertEqual(len(cset.entries), 2) 162 self.assertEqual(cset.date, datetime(1996, 10, 18, 13, 48, 45 ))163 self.assertEqual(cset.date, datetime(1996, 10, 18, 13, 48, 45, 0, UTC)) 163 164 164 165 def testBranchesInLog(self): … … 193 194 cset = csets.next() 194 195 self.assertEqual(cset.author, "tiran") 195 self.assertEqual(cset.date, datetime(2004, 8, 6, 20, 13, 30 ))196 self.assertEqual(cset.date, datetime(2004, 8, 6, 20, 13, 30, 0, UTC)) 196 197 self.assertEqual(cset.log, "Added ExtendingType") 197 198 entry = cset.entries[0] … … 202 203 cset = csets.next() 203 204 self.assertEqual(cset.author, "tiran") 204 self.assertEqual(cset.date, datetime(2004, 8, 9, 7, 44, 9 ))205 self.assertEqual(cset.date, datetime(2004, 8, 9, 7, 44, 9, 0, UTC)) 205 206 self.assertEqual(cset.log, """\ 206 207 Recoded migration walkers to use a generator instead returning a list to make them much more memory efficient. … … 216 217 cset = csets.next() 217 218 self.assertEqual(cset.author, "tiran") 218 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 15, 46 ))219 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 15, 46, 0, UTC)) 219 220 self.assertEqual(cset.log, "Fixed typo") 220 221 221 222 cset = csets.next() 222 223 self.assertEqual(cset.author, "tiran") 223 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 21, 24 ))224 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 21, 24, 0, UTC)) 224 225 self.assertEqual(cset.log, "Something went wrong ...") 225 226 226 227 cset = csets.next() 227 228 self.assertEqual(cset.author, "tiran") 228 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 21, 53 ))229 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 21, 53, 0, UTC)) 229 230 self.assertEqual(cset.log, "Somehow I mixed up two sentences") 230 231 231 232 cset = csets.next() 232 233 self.assertEqual(cset.author, "rochael") 233 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 59, 55 ))234 self.assertEqual(cset.date, datetime(2004, 8, 13, 13, 59, 55, 0, UTC)) 234 235 self.assertEqual(cset.log, "removed duplicated ENABLE_TEMPLATE_MIXIN") 235 236 entry = cset.entries[0] … … 354 355 355 356 cset = csets[0] 356 self.assertEqual(cset.date, datetime(1994, 5, 17, 13, 03, 36 ))357 self.assertEqual(cset.date, datetime(1994, 5, 17, 13, 03, 36, 0, UTC)) 357 358 358 359 cset = csets[-1] 359 self.assertEqual(cset.date, datetime(1995, 12, 30, 18, 32, 46 ))360 self.assertEqual(cset.date, datetime(1995, 12, 30, 18, 32, 46, 0, UTC)) 360 361 361 362 class CvsRevisions(TestCase): -
vcpx/tests/darcs.py
r1208 r1216 11 11 from vcpx.repository.darcs import changesets_from_darcschanges 12 12 from vcpx.shwrap import ExternalCommand, PIPE 13 from vcpx.tzinfo import UTC 13 14 14 15 … … 55 56 "Fix the CVS parser to omit already seen changesets") 56 57 self.assertEqual(cset.author, "lele@nautilus.homeip.net") 57 self.assertEqual(cset.date, datetime(2004, 7, 16, 12, 37, 37 ))58 self.assertEqual(cset.date, datetime(2004, 7, 16, 12, 37, 37, 0, UTC)) 58 59 self.assertEqual(cset.log, "For some unknown reasons....") 59 60 entry = cset.entries[0] … … 64 65 self.assertEqual(cset.revision, 65 66 "Svn log parser with test") 66 self.assertEqual(cset.date, datetime(2004, 6, 1, 14, 5, 59 ))67 self.assertEqual(cset.date, datetime(2004, 6, 1, 14, 5, 59, 0, UTC)) 67 68 self.assertEqual(len(cset.entries), 4) 68 69 self.assertEqual(cset.darcs_hash, … … 213 214 214 215 cset = csets.next() 215 self.assertEqual(cset.date, datetime(2003, 10, 14, 9, 42, 0 ))216 217 cset = csets.next() 218 self.assertEqual(cset.date, datetime(2003, 10, 14, 14, 2, 31 ))216 self.assertEqual(cset.date, datetime(2003, 10, 14, 9, 42, 0, 0, UTC)) 217 218 cset = csets.next() 219 self.assertEqual(cset.date, datetime(2003, 10, 14, 14, 2, 31, 0, UTC)) 219 220 220 221 RENAME_THEN_REMOVE_TEST = """ -
vcpx/tests/svn.py
r1180 r1216 9 9 from datetime import datetime 10 10 from vcpx.repository.svn import changesets_from_svnlog 11 from vcpx.tzinfo import UTC 11 12 12 13 … … 41 42 cset = csets.next() 42 43 self.assertEqual(cset.author, 'lele') 43 self.assertEqual(cset.date, datetime(2004,11,12,15,05,37,134366 ))44 self.assertEqual(cset.date, datetime(2004,11,12,15,05,37,134366,UTC)) 44 45 self.assertEqual(cset.log, 'create tree') 45 46 self.assertEqual(len(cset.entries), 2) … … 55 56 cset = csets.next() 56 57 self.assertEqual(cset.author, 'lele') 57 self.assertEqual(cset.date, datetime(2004,11,12,15,06,04,193650 ))58 self.assertEqual(cset.date, datetime(2004,11,12,15,06,04,193650,UTC)) 58 59 self.assertEqual(cset.log, 'rename dir') 59 60 self.assertEqual(len(cset.entries), 1) … … 75 76 cset = csets.next() 76 77 self.assertEqual(cset.author, 'anthony') 77 self.assertEqual(cset.date, datetime(2004,11,9,6,54,20,709243 ))78 self.assertEqual(cset.date, datetime(2004,11,9,6,54,20,709243,UTC)) 78 79 self.assertEqual(cset.log, 'Moving to a /sandbox') 79 80 self.assertEqual(len(cset.entries), 1) … … 95 96 cset = csets[1] 96 97 self.assertEqual(cset.author, 'lele') 97 self.assertEqual(cset.date, datetime(2005,1,8, 17,36,55,174757 ))98 self.assertEqual(cset.date, datetime(2005,1,8, 17,36,55,174757,UTC)) 98 99 self.assertEqual(cset.log, 'Copy') 99 100 self.assertEqual(len(cset.entries), 1) … … 105 106 106 107 cset = csets[2] 107 self.assertEqual(cset.date, datetime(2005,1,8, 17,42,41,347315 ))108 self.assertEqual(cset.date, datetime(2005,1,8, 17,42,41,347315,UTC)) 108 109 self.assertEqual(cset.log, 'Remove') 109 110 self.assertEqual(len(cset.entries), 1) … … 114 115 115 116 cset = csets[3] 116 self.assertEqual(cset.date, datetime(2005,1,8, 17,43,9,909127 ))117 self.assertEqual(cset.date, datetime(2005,1,8, 17,43,9,909127,UTC)) 117 118 self.assertEqual(cset.log, 'Move') 118 119 self.assertEqual(len(cset.entries), 1) … … 133 134 cset = csets.next() 134 135 self.assertEqual(cset.author, 'cmlenz') 135 self.assertEqual(cset.date, datetime(2005,3,21, 8,34, 2,522947 ))136 self.assertEqual(cset.date, datetime(2005,3,21, 8,34, 2,522947,UTC)) 136 137 self.assertEqual(len(cset.entries), 7) 137 138 -
vcpx/repository/monotone.py
r1215 r1216 22 22 from vcpx.target import SynchronizableTargetWorkingDir, TargetInitializationFailure 23 23 from vcpx.changes import Changeset 24 from vcpx.tzinfo import UTC 24 25 25 26 … … 241 242 y,m,d = map(int, day.split(day[4])) 242 243 hh,mm,ss = map(int, time.split(':')) 243 date = datetime(y,m,d,hh,mm,ss )244 date = datetime(y,m,d,hh,mm,ss,0,UTC) 244 245 self.dates.append(date) 245 246 state = self.SINGLE … … 764 765 log.close() 765 766 767 date = date.astimezone(UTC).replace(tzinfo=None) # monotone wants UTC 766 768 cmd = self.repository.command("commit", 767 769 "--author", encode(author), -
vcpx/repository/cdv.py
r1215 r1216 16 16 from vcpx.target import SynchronizableTargetWorkingDir, TargetInitializationFailure 17 17 from vcpx.source import ChangesetApplicationFailure 18 from vcpx.tzinfo import UTC 18 19 19 20 … … 82 83 cmd = self.repository.command("-u", encode(author), "commit", 83 84 "-m", encode('\n'.join(logmessage)), 84 "-D", date. strftime('%Y/%m/%d %H:%M:%S UTC'))85 "-D", date.astimezone(UTC).strftime('%Y/%m/%d %H:%M:%S UTC')) 85 86 86 87 if not entries: -
vcpx/repository/tla.py
r1209 r1216 50 50 GetUpstreamChangesetsFailure 51 51 from vcpx.target import TargetInitializationFailure 52 from vcpx.tzinfo import UTC, FixedOffset 52 53 53 54 … … 206 207 if err: 207 208 raise GetUpstreamChangesetsFailure(str(err)) 208 y,m,d,hh,mm,ss,d1,d2,d3 = strptime(msg['Standard-date'], 209 "%Y-%m-%d %H:%M:%S %Z") 210 date = datetime(y,m,d,hh,mm,ss) 209 210 date = self.__parse_date(msg['Date'], msg['Standard-date']) 211 211 author = msg['Creator'] 212 212 revision = fqrev … … 221 221 changesets.append(Changeset(revision, date, author, logmsg)) 222 222 return changesets 223 224 def __parse_date(self, d1, d2): 225 # d1: Wed Dec 10 15:01:28 EST 2003 226 # d2: 2003-12-10 04:01:28 GMT 227 228 d1 = datetime(*strptime(d1[:19] + d1[-5:], '%a %b %d %H:%M:%S %Y')[:6]).replace(tzinfo=UTC) 229 d2 = datetime(*strptime(d2[:19], '%Y-%m-%d %H:%M:%S')[:6]).replace(tzinfo=UTC) 230 231 offset = d1 - d2 232 offset = offset.seconds + offset.days * 24 * 3600 233 234 return d1.replace(tzinfo=FixedOffset(offset/60)) 223 235 224 236 def __hide_foreign_entries(self): -
vcpx/repository/bzr.py
r1215 r1216 113 113 from datetime import datetime 114 114 from vcpx.changes import ChangesetEntry, Changeset 115 from vcpx.tzinfo import FixedOffset, UTC 115 116 116 117 revision = branch.repository.get_revision(revision_id) … … 139 140 entries.append(e) 140 141 142 if revision.timezone is not None: 143 timezone = FixedOffset(revision.timezone / 60) 144 else: 145 timezone = UTC 146 141 147 return Changeset(revision.revision_id, 142 datetime.fromtimestamp(revision.timestamp ),148 datetime.fromtimestamp(revision.timestamp, timezone), 143 149 revision.committer, 144 150 revision.message, … … 226 232 Commit the changeset. 227 233 """ 228 from time import mktime234 from calendar import timegm # like mktime(), but returns UTC timestamp 229 235 from binascii import hexlify 230 236 from re import search … … 242 248 self.log.info('Committing...') 243 249 logmessage = "Empty changelog" 244 timestamp = int(mktime(date.timetuple())) 250 251 timestamp = timegm(date.utctimetuple()) 252 timezone = date.utcoffset().seconds + date.utcoffset().days * 24 * 3600 245 253 246 254 # Guess sane email address … … 262 270 specific_files=entries, rev_id=revision_id, 263 271 verbose=self.repository.projectref().verbose, 264 timestamp=timestamp )272 timestamp=timestamp, timezone=timezone) 265 273 266 274 def _removePathnames(self, names): -
vcpx/repository/cg.py
r1215 r1216 106 106 env['GIT_AUTHOR_EMAIL']=email 107 107 if date: 108 env['GIT_AUTHOR_DATE']= str(date)108 env['GIT_AUTHOR_DATE']=date.strftime('%Y-%m-%d %H:%M:%S %z') 109 109 # '-f' flag means we can get empty commits, which 110 110 # shouldn't be a problem. -
vcpx/repository/git/target.py
r1215 r1216 18 18 from vcpx.config import ConfigurationError 19 19 from vcpx.target import SynchronizableTargetWorkingDir, TargetInitializationFailure 20 from vcpx.tzinfo import FixedOffset 20 21 21 22 from vcpx import TailorException … … 27 28 "Specified branchpoint not found in parent branch" 28 29 30 ## generic stuff 31 32 class GitRepository(Repository): 33 METADIR = '.git' 34 35 def _load(self, project): 36 Repository._load(self, project) 37 self.EXECUTABLE = project.config.get(self.name, 'git-command', 'git') 38 self.PARENT_REPO = project.config.get(self.name, 'parent-repo') 39 self.BRANCHPOINT = project.config.get(self.name, 'branchpoint', 'HEAD') 40 self.BRANCHNAME = project.config.get(self.name, 'branch') 41 if self.BRANCHNAME: 42 self.BRANCHNAME = 'refs/heads/' + self.BRANCHNAME 43 44 if self.repository and self.PARENT_REPO: 45 self.log.critical('Cannot make sense of both "repository" and "parent-repo" parameters') 46 raise ConfigurationError ('Must specify only one of "repository" and "parent-repo"') 47 48 if self.BRANCHNAME and not self.repository: 49 self.log.critical('Cannot make sense of "branch" if "repository" is not set') 50 raise ConfigurationError ('Missing "repository" to make use o "branch"') 51 52 self.env = {} 53 54 if self.repository: 55 self.storagedir = self.repository 56 self.env['GIT_DIR'] = self.storagedir 57 self.env['GIT_INDEX_FILE'] = self.METADIR + '/index' 58 else: 59 self.storagedir = self.METADIR 60 61 def _tryCommand(self, cmd, exception=Exception, pipe=True): 62 c = GitExternalCommand(self, 63 command = self.command(*cmd), cwd = self.basedir) 64 if pipe: 65 output = c.execute(stdout=PIPE)[0] 66 else: 67 c.execute() 68 if c.exit_status: 69 raise exception(str(c) + ' failed') 70 if pipe: 71 return output.read().split('\n') 72 73 class GitExternalCommand(ExternalCommand): 74 def __init__(self, repo, command=None, cwd=None): 75 """ 76 Initialize an ExternalCommand instance tied to a GitRepository 77 from which it inherits a set of environment variables to use 78 for each execute(). 79 """ 80 81 self.repo = repo 82 return ExternalCommand.__init__(self, command, cwd) 83 84 def execute(self, *args, **kwargs): 85 """Execute the command, with controlled environment.""" 86 87 if not kwargs.has_key('env'): 88 kwargs['env'] = {} 89 90 kwargs['env'].update(self.repo.env) 91 92 return ExternalCommand.execute(self, *args, **kwargs) 93 94 class GitWorkingDir(UpdatableSourceWorkingDir, SynchronizableTargetWorkingDir): 95 96 ## UpdatableSourceWorkingDir 97 98 def _checkoutUpstreamRevision(self, revision): 99 """ git clone """ 100 from os import rename, rmdir 101 from os.path import join 102 103 # Right now we clone the entire repository and just check out to the 104 # current rev because it makes revision parsing easier. We can't 105 # easily check out arbitrary revisions anyway, but we could probably 106 # handle HEAD (master) as a special case... 107 # git clone won't checkout into an existing directory 108 target = join(self.repository.basedir, '.gittmp') 109 # might want -s if we can determine that the path is local. Then again, 110 # that makes it a little unsafe to do git write actions here 111 self.repository._tryCommand(['clone', '-n', self.repository.repository, target], 112 ChangesetApplicationFailure, False) 113 114 rename(join(target, '.git'), join(self.repository.basedir, '.git')) 115 rmdir(target) 116 117 rev = self._getRev(revision) 118 if rev != revision: 119 self.log.info('Checking out revision %s (%s)' % (rev, revision)) 120 else: 121 self.log.info('Checking out revision ' + rev) 122 self.repository._tryCommand(['reset', '--hard', rev], ChangesetApplicationFailure, False) 123 124 return self._changesetForRevision(rev) 125 126 def _getUpstreamChangesets(self, since): 127 self.repository._tryCommand(['fetch'], GetUpstreamChangesetsFailure, False) 128 129 revs = self.repository._tryCommand(['rev-list', '^' + since, 'origin'], 130 GetUpstreamChangesetsFailure)[:-1] 131 revs.reverse() 132 for rev in revs: 133 self.log.info('Updating to revision ' + rev) 134 yield self._changesetForRevision(rev) 135 136 def _applyChangeset(self, changeset): 137 out = self.repository._tryCommand(['merge', '-n', '--no-commit', 'fastforward', 138 'HEAD', changeset.revision], 139 ChangesetApplicationFailure) 140 141 conflicts = [] 142 for line in out: 143 if line.endswith(': needs update'): 144 conflicts.append(line[:-14]) 145 146 if conflicts: 147 self.log.warning("Conflict after 'git merge': %s", ' '.join(conflicts)) 148 149 return conflicts 150 151 def _changesetForRevision(self, revision): 152 from datetime import datetime 153 from vcpx.changes import Changeset, ChangesetEntry 154 155 action_map = {'A': ChangesetEntry.ADDED, 'D': ChangesetEntry.DELETED, 156 'M': ChangesetEntry.UPDATED, 'R': ChangesetEntry.RENAMED} 157 158 # find parent 159 lines = self.repository._tryCommand(['rev-list', '--pretty=raw', '--max-count=1', revision], 160 GetUpstreamChangesetsFailure) 161 parents = [] 162 user = Changeset.ANONYMOUS_USER 163 loglines = [] 164 date = None 165 for line in lines: 166 if line.startswith('parent'): 167 parents.append(line.split(' ').pop()) 168 if line.startswith('author'): 169 author_fields = line.split(' ')[1:] 170 tz = int(author_fields.pop()) 171 dt = int(author_fields.pop()) 172 user = ' '.join(author_fields) 173 tzsecs = abs(tz) 174 tzsecs = (tzsecs / 100 * 60 + tzsecs % 100) * 60 175 if tz < 0: 176 tzsecs = -tzsecs 177 date = datetime.utcfromtimestamp(dt + tzsecs) 178 if line.startswith(' '): 179 loglines.append(line.lstrip(' ')) 180 181 message = '\n'.join(loglines) 182 entries = [] 183 cmd = ['diff-tree', '--root', '-r', '-M', '--name-status'] 184 # haven't thought about merges yet... 185 if parents: 186 cmd.append(parents[0]) 187 cmd.append(revision) 188 files = self.repository._tryCommand(cmd, GetUpstreamChangesetsFailure)[:-1] 189 if not parents: 190 # git lets us know what it's diffing against if we omit parent 191 if len(files) > 0: 192 files.pop(0) 193 for line in files: 194 fields = line.split('\t') 195 state = fields.pop(0) 196 name = fields.pop() 197 e = ChangesetEntry(name) 198 e.action_kind = action_map[state[0]] 199 if e.action_kind == ChangesetEntry.RENAMED: 200 e.old_name = fields.pop() 201 202 entries.append(e) 203 204 # Brute-force tag search 205 from os.path import join 206 from os import listdir 207 208 tags = [] 209 tagdir = join(self.repository.basedir, '.git', 'refs', 'tags') 210 try: 211 for tag in listdir(tagdir): 212 # Consider caching stat info per tailor run 213 tagrev = self.repository._tryCommand(['rev-list', '--max-count=1', tag])[0] 214 if (tagrev == revision): 215 tags.append(tag) 216 except OSError: 217 # No tag dir 218 pass 219 220 return Changeset(revision, date, user, message, entries, tags=tags) 221 222 def _getRev(self, revision): 223 """ Return the git object corresponding to the symbolic revision """ 224 if revision == 'INITIAL': 225 return self.repository._tryCommand(['rev-list', 'HEAD'], GetUpstreamChangesetsFailure)[-2] 226 227 return self.repository._tryCommand(['rev-parse', '--verify', revision], GetUpstreamChangesetsFailure)[0] 29 228 30 229 class GitTargetWorkingDir(SynchronizableTargetWorkingDir): … … 117 316 env['GIT_COMMITTER_EMAIL']=email 118 317 if date: 119 env['GIT_AUTHOR_DATE']=date.strftime("%Y-%m-%d %H:%M:%S ")318 env['GIT_AUTHOR_DATE']=date.strftime("%Y-%m-%d %H:%M:%S %z") 120 319 env['GIT_COMMITTER_DATE']=env['GIT_AUTHOR_DATE'] 121 320 if parent: -
vcpx/repository/hg.py
r1209 r1216 122 122 from datetime import datetime 123 123 from vcpx.changes import Changeset, ChangesetEntry 124 from vcpx.tzinfo import FixedOffset 124 125 125 126 entries = [] … … 128 129 (manifest, user, date, files, message) = repo.changelog.read(node) 129 130 130 # Different targets seem to handle the TZ differently. It looks like131 # darcs may be the most correct.132 131 dt, tz = date 133 date = datetime.fromtimestamp( int(dt) + int(tz))132 date = datetime.fromtimestamp(dt, FixedOffset(-tz/60)) # note the minus sign! 134 133 135 134 manifest = repo.manifest.read(manifest) … … 252 251 253 252 def _commit(self, date, author, patchname, changelog=None, names=[]): 254 from time import mktime253 from calendar import timegm # like mktime(), but returns UTC timestamp 255 254 256 255 encode = self.repository.encode … … 267 266 self.log.info('Committing...') 268 267 logmessage = "Empty changelog" 268 269 timestamp = timegm(date.utctimetuple()) 270 timezone = date.utcoffset().seconds + date.utcoffset().days * 24 * 3600 271 269 272 opts = {} 270 273 opts['message'] = logmessage 271 274 opts['user'] = encode(author) 272 opts['date'] = '%d 0' % mktime(date.timetuple())275 opts['date'] = '%d %d' % (timestamp, -timezone) # note the minus sign! 273 276 self._hgCommand('commit', *[encode(n) for n in names], **opts) 274 277
Note: See TracChangeset
for help on using the changeset viewer.
