mercurial/commands.py
changeset 4258 47ba52121433
parent 4256 fe0fe0b4d73b
child 4259 bda63383d529
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')),