comparison mercurial/commands.py @ 4258:47ba52121433

Add import --exact. When this option is set, import will apply the patch (which must be generated by export) to the parents specified in the patch, and check that the node produced by the patch matches the node ID in the patch.
author Brendan Cully <brendan@kublai.com>
date Thu, 22 Mar 2007 10:44:59 -0700
parents fe0fe0b4d73b
children bda63383d529
comparison
equal deleted inserted replaced
4257:f51317e24114 4258:47ba52121433
1475 text/x-patch to be used). From and Subject headers of email 1475 text/x-patch to be used). From and Subject headers of email
1476 message are used as default committer and commit message. All 1476 message are used as default committer and commit message. All
1477 text/plain body parts before first diff are added to commit 1477 text/plain body parts before first diff are added to commit
1478 message. 1478 message.
1479 1479
1480 If imported patch was generated by hg export, user and description 1480 If the imported patch was generated by hg export, user and description
1481 from patch override values from message headers and body. Values 1481 from patch override values from message headers and body. Values
1482 given on command line with -m and -u override these. 1482 given on command line with -m and -u override these.
1483 1483
1484 If --exact is specified, import will set the working directory
1485 to the parent of each patch before applying it, and will abort
1486 if the resulting changeset has a different ID than the one
1487 recorded in the patch. This may happen due to character set
1488 problems or other deficiencies in the text patch format.
1489
1484 To read a patch from standard input, use patch name "-". 1490 To read a patch from standard input, use patch name "-".
1485 """ 1491 """
1486 patches = (patch1,) + patches 1492 patches = (patch1,) + patches
1487 1493
1488 if not opts['force']: 1494 if opts.get('exact') or not opts['force']:
1489 bail_if_changed(repo) 1495 bail_if_changed(repo)
1490 1496
1491 d = opts["base"] 1497 d = opts["base"]
1492 strip = opts["strip"] 1498 strip = opts["strip"]
1493 1499
1497 for p in patches: 1503 for p in patches:
1498 pf = os.path.join(d, p) 1504 pf = os.path.join(d, p)
1499 1505
1500 if pf == '-': 1506 if pf == '-':
1501 ui.status(_("applying patch from stdin\n")) 1507 ui.status(_("applying patch from stdin\n"))
1502 tmpname, message, user, date = patch.extract(ui, sys.stdin) 1508 tmpname, message, user, date, nodeid, p1, p2 = patch.extract(ui, sys.stdin)
1503 else: 1509 else:
1504 ui.status(_("applying %s\n") % p) 1510 ui.status(_("applying %s\n") % p)
1505 tmpname, message, user, date = patch.extract(ui, file(pf)) 1511 tmpname, message, user, date, nodeid, p1, p2 = patch.extract(ui, file(pf))
1506 1512
1507 if tmpname is None: 1513 if tmpname is None:
1508 raise util.Abort(_('no diffs found')) 1514 raise util.Abort(_('no diffs found'))
1509 1515
1510 try: 1516 try:
1519 # launch the editor 1525 # launch the editor
1520 message = None 1526 message = None
1521 ui.debug(_('message:\n%s\n') % message) 1527 ui.debug(_('message:\n%s\n') % message)
1522 1528
1523 files = {} 1529 files = {}
1530 if opts.get('exact'):
1531 if not nodeid or not p1:
1532 raise util.Abort(_('not a mercurial patch'))
1533 p1 = repo.lookup(p1)
1534 p2 = repo.lookup(p2 or hex(nullid))
1535
1536 wctx = repo.workingctx()
1537 wp = repo.workingctx().parents()
1538 if p1 != wp[0].node():
1539 hg.clean(repo, p1, wlock=wlock)
1540 repo.dirstate.setparents(p1, p2)
1524 try: 1541 try:
1525 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root, 1542 fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
1526 files=files) 1543 files=files)
1527 finally: 1544 finally:
1528 files = patch.updatedir(ui, repo, files, wlock=wlock) 1545 files = patch.updatedir(ui, repo, files, wlock=wlock)
1529 repo.commit(files, message, user, date, wlock=wlock, lock=lock) 1546 n = repo.commit(files, message, user, date, wlock=wlock, lock=lock)
1547 if opts.get('exact'):
1548 if hex(n) != nodeid:
1549 repo.rollback()
1550 raise util.Abort(_('patch is damaged or loses information'))
1530 finally: 1551 finally:
1531 os.unlink(tmpname) 1552 os.unlink(tmpname)
1532 1553
1533 def incoming(ui, repo, source="default", **opts): 1554 def incoming(ui, repo, source="default", **opts):
1534 """show new changesets found in source 1555 """show new changesets found in source
2770 [('p', 'strip', 1, 2791 [('p', 'strip', 1,
2771 _('directory strip option for patch. This has the same\n' 2792 _('directory strip option for patch. This has the same\n'
2772 'meaning as the corresponding patch option')), 2793 'meaning as the corresponding patch option')),
2773 ('b', 'base', '', _('base path')), 2794 ('b', 'base', '', _('base path')),
2774 ('f', 'force', None, 2795 ('f', 'force', None,
2775 _('skip check for outstanding uncommitted changes'))] + commitopts, 2796 _('skip check for outstanding uncommitted changes')),
2797 ('', 'exact', None,
2798 _('apply patch to the nodes from which it was generated'))] + commitopts,
2776 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')), 2799 _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')),
2777 "incoming|in": (incoming, 2800 "incoming|in": (incoming,
2778 [('M', 'no-merges', None, _('do not show merges')), 2801 [('M', 'no-merges', None, _('do not show merges')),
2779 ('f', 'force', None, 2802 ('f', 'force', None,
2780 _('run even when remote repository is unrelated')), 2803 _('run even when remote repository is unrelated')),