##// END OF EJS Templates
convert: option to set date and time for svn commits...
Nikita Slyusarev -
r47129:7525e77b default
parent child Browse files
Show More
@@ -491,6 +491,22 b' def convert(ui, src, dest=None, revmapfi'
491 491
492 492 :convert.skiptags: does not convert tags from the source repo to the target
493 493 repo. The default is False.
494
495 Subversion Destination
496 ######################
497
498 Original commit dates are not preserved by default.
499
500 :convert.svn.dangerous-set-commit-dates: preserve original commit dates,
501 forcefully setting ``svn:date`` revision properties. This option is
502 DANGEROUS and may break some subversion functionality for the resulting
503 repository (e.g. filtering revisions with date ranges in ``svn log``),
504 as original commit dates are not guaranteed to be monotonically
505 increasing.
506
507 For commit dates setting to work destination repository must have
508 ``pre-revprop-change`` hook configured to allow setting of ``svn:date``
509 revision properties. See Subversion documentation for more details.
494 510 """
495 511 return convcmd.convert(ui, src, dest, revmapfile, **opts)
496 512
@@ -97,6 +97,17 b' def fs2svn(s):'
97 97 return s.decode(fsencoding).encode('utf-8')
98 98
99 99
100 def formatsvndate(date):
101 return dateutil.datestr(date, b'%Y-%m-%dT%H:%M:%S.000000Z')
102
103
104 def parsesvndate(s):
105 # Example SVN datetime. Includes microseconds.
106 # ISO-8601 conformant
107 # '2007-01-04T17:35:00.902377Z'
108 return dateutil.parsedate(s[:19] + b' UTC', [b'%Y-%m-%dT%H:%M:%S'])
109
110
100 111 class SvnPathNotFound(Exception):
101 112 pass
102 113
@@ -1158,12 +1169,7 b' class svn_source(converter_source):'
1158 1169 continue
1159 1170 paths.append((path, ent))
1160 1171
1161 # Example SVN datetime. Includes microseconds.
1162 # ISO-8601 conformant
1163 # '2007-01-04T17:35:00.902377Z'
1164 date = dateutil.parsedate(
1165 date[:19] + b" UTC", [b"%Y-%m-%dT%H:%M:%S"]
1166 )
1172 date = parsesvndate(date)
1167 1173 if self.ui.configbool(b'convert', b'localtimezone'):
1168 1174 date = makedatetimestamp(date[0])
1169 1175
@@ -1380,7 +1386,7 b' class svn_source(converter_source):'
1380 1386 return logstream(stdout)
1381 1387
1382 1388
1383 pre_revprop_change = b'''#!/bin/sh
1389 pre_revprop_change_template = b'''#!/bin/sh
1384 1390
1385 1391 REPOS="$1"
1386 1392 REV="$2"
@@ -1388,15 +1394,26 b' USER="$3"'
1388 1394 PROPNAME="$4"
1389 1395 ACTION="$5"
1390 1396
1391 if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi
1392 if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-branch" ]; then exit 0; fi
1393 if [ "$ACTION" = "A" -a "$PROPNAME" = "hg:convert-rev" ]; then exit 0; fi
1397 %(rules)s
1394 1398
1395 1399 echo "Changing prohibited revision property" >&2
1396 1400 exit 1
1397 1401 '''
1398 1402
1399 1403
1404 def gen_pre_revprop_change_hook(prop_actions_allowed):
1405 rules = []
1406 for action, propname in prop_actions_allowed:
1407 rules.append(
1408 (
1409 b'if [ "$ACTION" = "%s" -a "$PROPNAME" = "%s" ]; '
1410 b'then exit 0; fi'
1411 )
1412 % (action, propname)
1413 )
1414 return pre_revprop_change_template % {b'rules': b'\n'.join(rules)}
1415
1416
1400 1417 class svn_sink(converter_sink, commandline):
1401 1418 commit_re = re.compile(br'Committed revision (\d+).', re.M)
1402 1419 uuid_re = re.compile(br'Repository UUID:\s*(\S+)', re.M)
@@ -1470,9 +1487,20 b' class svn_sink(converter_sink, commandli'
1470 1487 self.is_exec = None
1471 1488
1472 1489 if created:
1490 prop_actions_allowed = [
1491 (b'M', b'svn:log'),
1492 (b'A', b'hg:convert-branch'),
1493 (b'A', b'hg:convert-rev'),
1494 ]
1495
1496 if self.ui.configbool(
1497 b'convert', b'svn.dangerous-set-commit-dates'
1498 ):
1499 prop_actions_allowed.append((b'M', b'svn:date'))
1500
1473 1501 hook = os.path.join(created, b'hooks', b'pre-revprop-change')
1474 1502 fp = open(hook, b'wb')
1475 fp.write(pre_revprop_change)
1503 fp.write(gen_pre_revprop_change_hook(prop_actions_allowed))
1476 1504 fp.close()
1477 1505 util.setflags(hook, False, True)
1478 1506
@@ -1667,6 +1695,23 b' class svn_sink(converter_sink, commandli'
1667 1695 revprop=True,
1668 1696 revision=rev,
1669 1697 )
1698
1699 if self.ui.configbool(
1700 b'convert', b'svn.dangerous-set-commit-dates'
1701 ):
1702 # Subverson always uses UTC to represent date and time
1703 date = dateutil.parsedate(commit.date)
1704 date = (date[0], 0)
1705
1706 # The only way to set date and time for svn commit is to use propset after commit is done
1707 self.run(
1708 b'propset',
1709 b'svn:date',
1710 formatsvndate(date),
1711 revprop=True,
1712 revision=rev,
1713 )
1714
1670 1715 for parent in parents:
1671 1716 self.addchild(parent, rev)
1672 1717 return self.revid(rev)
@@ -570,6 +570,11 b' coreconfigitem('
570 570 default=0,
571 571 )
572 572 coreconfigitem(
573 b'convert',
574 b'svn.dangerous-set-commit-dates',
575 default=False,
576 )
577 coreconfigitem(
573 578 b'debug',
574 579 b'dirstate.delaywrite',
575 580 default=0,
@@ -15,6 +15,7 b' def parseentry(entry):'
15 15 e['revision'] = entry.getAttribute('revision')
16 16 e['author'] = xmltext(entry.getElementsByTagName('author')[0])
17 17 e['msg'] = xmltext(entry.getElementsByTagName('msg')[0])
18 e['date'] = xmltext(entry.getElementsByTagName('date')[0])
18 19 e['paths'] = []
19 20 paths = entry.getElementsByTagName('paths')
20 21 if paths:
@@ -42,7 +43,7 b' def printentries(entries):'
42 43 except AttributeError:
43 44 fp = sys.stdout
44 45 for e in entries:
45 for k in ('revision', 'author', 'msg'):
46 for k in ('revision', 'author', 'date', 'msg'):
46 47 fp.write(('%s: %s\n' % (k, e[k])).encode('utf-8'))
47 48 for path, action, fpath, frev in sorted(e['paths']):
48 49 frominfo = b''
@@ -54,10 +54,12 b' Modify'
54 54 2 2 test a
55 55 revision: 2
56 56 author: test
57 date: * (glob)
57 58 msg: modify a file
58 59 M /a
59 60 revision: 1
60 61 author: test
62 date: * (glob)
61 63 msg: add a file
62 64 A /a
63 65 A /d1
@@ -95,6 +97,7 b' Rename'
95 97 3 3 test b
96 98 revision: 3
97 99 author: test
100 date: * (glob)
98 101 msg: rename a file
99 102 D /a
100 103 A /b (from /a@2)
@@ -131,6 +134,7 b' Copy'
131 134 4 4 test c
132 135 revision: 4
133 136 author: test
137 date: * (glob)
134 138 msg: copy a file
135 139 A /c (from /b@3)
136 140 $ ls a a-hg-wc
@@ -167,6 +171,7 b' Remove'
167 171 5 5 test .
168 172 revision: 5
169 173 author: test
174 date: * (glob)
170 175 msg: remove a file
171 176 D /b
172 177 $ ls a a-hg-wc
@@ -209,6 +214,7 b' Executable'
209 214 6 6 test c
210 215 revision: 6
211 216 author: test
217 date: * (glob)
212 218 msg: make a file executable
213 219 M /c
214 220 #if execbit
@@ -247,6 +253,7 b' Symlinks'
247 253 8 8 test newlink
248 254 revision: 8
249 255 author: test
256 date: * (glob)
250 257 msg: move symlink
251 258 D /link
252 259 A /newlink (from /link@7)
@@ -278,6 +285,7 b' Convert with --full adds and removes fil'
278 285 7 7 test f
279 286 revision: 7
280 287 author: test
288 date: * (glob)
281 289 msg: f
282 290 D /c
283 291 A /d
@@ -315,6 +323,7 b' Executable in new directory'
315 323 1 1 test d1/a
316 324 revision: 1
317 325 author: test
326 date: * (glob)
318 327 msg: add executable file in new directory
319 328 A /d1
320 329 A /d1/a
@@ -343,6 +352,7 b' Copy to new directory'
343 352 2 2 test d2/a
344 353 revision: 2
345 354 author: test
355 date: * (glob)
346 356 msg: copy file to new directory
347 357 A /d2
348 358 A /d2/a (from /d1/a@1)
@@ -416,21 +426,25 b' Expect 4 changes'
416 426 4 4 test right-2
417 427 revision: 4
418 428 author: test
429 date: * (glob)
419 430 msg: merge
420 431 A /right-1
421 432 A /right-2
422 433 revision: 3
423 434 author: test
435 date: * (glob)
424 436 msg: left-2
425 437 M /b
426 438 A /left-2
427 439 revision: 2
428 440 author: test
441 date: * (glob)
429 442 msg: left-1
430 443 M /b
431 444 A /left-1
432 445 revision: 1
433 446 author: test
447 date: * (glob)
434 448 msg: base
435 449 A /b
436 450
@@ -459,10 +473,12 b' Tags are not supported, but must not bre'
459 473 2 2 test .hgtags
460 474 revision: 2
461 475 author: test
476 date: * (glob)
462 477 msg: Tagged as v1.0
463 478 A /.hgtags
464 479 revision: 1
465 480 author: test
481 date: * (glob)
466 482 msg: Add file a
467 483 A /a
468 484 $ rm -rf a a-hg a-hg-wc
@@ -494,10 +510,12 b' Executable bit removal'
494 510 2 2 test exec
495 511 revision: 2
496 512 author: test
513 date: * (glob)
497 514 msg: remove executable bit
498 515 M /exec
499 516 revision: 1
500 517 author: test
518 date: * (glob)
501 519 msg: create executable
502 520 A /exec
503 521 $ test ! -x a-hg-wc/exec
@@ -540,11 +558,77 b' Skipping empty commits'
540 558 2 2 test b
541 559 revision: 2
542 560 author: test
561 date: * (glob)
543 562 msg: Another change
544 563 A /b
545 564 revision: 1
546 565 author: test
566 date: * (glob)
547 567 msg: Some change
548 568 A /a
549 569
550 570 $ rm -rf a a-hg a-hg-wc
571
572 Commit dates convertion
573
574 $ hg init a
575
576 $ echo a >> a/a
577 $ hg add a
578 adding a/a
579 $ hg --cwd a ci -d '1 0' -A -m 'Change 1'
580
581 $ echo a >> a/a
582 $ hg --cwd a ci -d '2 0' -m 'Change 2'
583
584 $ echo a >> a/a
585 $ hg --cwd a ci -d '2 0' -m 'Change at the same time'
586
587 $ echo a >> a/a
588 $ hg --cwd a ci -d '1 0' -m 'Change in the past'
589
590 $ echo a >> a/a
591 $ hg --cwd a ci -d '3 0' -m 'Change in the future'
592
593 $ hg convert --config convert.svn.dangerous-set-commit-dates=true -d svn a
594 assuming destination a-hg
595 initializing svn repository 'a-hg'
596 initializing svn working copy 'a-hg-wc'
597 scanning source...
598 sorting...
599 converting...
600 4 Change 1
601 3 Change 2
602 2 Change at the same time
603 1 Change in the past
604 0 Change in the future
605 $ svnupanddisplay a-hg-wc 0
606 5 5 test .
607 5 5 test a
608 revision: 5
609 author: test
610 date: 1970-01-01T00:00:03.000000Z
611 msg: Change in the future
612 M /a
613 revision: 4
614 author: test
615 date: 1970-01-01T00:00:01.000000Z
616 msg: Change in the past
617 M /a
618 revision: 3
619 author: test
620 date: 1970-01-01T00:00:02.000000Z
621 msg: Change at the same time
622 M /a
623 revision: 2
624 author: test
625 date: 1970-01-01T00:00:02.000000Z
626 msg: Change 2
627 M /a
628 revision: 1
629 author: test
630 date: 1970-01-01T00:00:01.000000Z
631 msg: Change 1
632 A /a
633
634 $ rm -rf a a-hg a-hg-wc
@@ -388,6 +388,23 b''
388 388 does not convert tags from the source repo to the target
389 389 repo. The default is False.
390 390
391 Subversion Destination
392 ######################
393
394 Original commit dates are not preserved by default.
395
396 convert.svn.dangerous-set-commit-dates
397 preserve original commit dates, forcefully setting
398 "svn:date" revision properties. This option is DANGEROUS and
399 may break some subversion functionality for the resulting
400 repository (e.g. filtering revisions with date ranges in
401 "svn log"), as original commit dates are not guaranteed to
402 be monotonically increasing.
403
404 For commit dates setting to work destination repository must have "pre-
405 revprop-change" hook configured to allow setting of "svn:date" revision
406 properties. See Subversion documentation for more details.
407
391 408 options ([+] can be repeated):
392 409
393 410 -s --source-type TYPE source repository type
General Comments 0
You need to be logged in to leave comments. Login now