Mercurial > public > mercurial-scm > hg
diff mercurial/commands.py @ 4263: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 |
line wrap: on
line diff
--- a/mercurial/commands.py Thu Mar 22 10:40:28 2007 -0700 +++ b/mercurial/commands.py Thu Mar 22 10:44:59 2007 -0700 @@ -1477,15 +1477,21 @@ text/plain body parts before first diff are added to commit message. - If imported patch was generated by hg export, user and description + If the imported patch was generated by hg export, user and description from patch override values from message headers and body. Values given on command line with -m and -u override these. + If --exact is specified, import will set the working directory + to the parent of each patch before applying it, and will abort + if the resulting changeset has a different ID than the one + recorded in the patch. This may happen due to character set + problems or other deficiencies in the text patch format. + To read a patch from standard input, use patch name "-". """ patches = (patch1,) + patches - if not opts['force']: + if opts.get('exact') or not opts['force']: bail_if_changed(repo) d = opts["base"] @@ -1499,10 +1505,10 @@ if pf == '-': ui.status(_("applying patch from stdin\n")) - tmpname, message, user, date = patch.extract(ui, sys.stdin) + tmpname, message, user, date, nodeid, p1, p2 = patch.extract(ui, sys.stdin) else: ui.status(_("applying %s\n") % p) - tmpname, message, user, date = patch.extract(ui, file(pf)) + tmpname, message, user, date, nodeid, p1, p2 = patch.extract(ui, file(pf)) if tmpname is None: raise util.Abort(_('no diffs found')) @@ -1521,12 +1527,27 @@ ui.debug(_('message:\n%s\n') % message) files = {} + if opts.get('exact'): + if not nodeid or not p1: + raise util.Abort(_('not a mercurial patch')) + p1 = repo.lookup(p1) + p2 = repo.lookup(p2 or hex(nullid)) + + wctx = repo.workingctx() + wp = repo.workingctx().parents() + if p1 != wp[0].node(): + hg.clean(repo, p1, wlock=wlock) + repo.dirstate.setparents(p1, p2) try: fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root, files=files) finally: files = patch.updatedir(ui, repo, files, wlock=wlock) - repo.commit(files, message, user, date, wlock=wlock, lock=lock) + n = repo.commit(files, message, user, date, wlock=wlock, lock=lock) + if opts.get('exact'): + if hex(n) != nodeid: + repo.rollback() + raise util.Abort(_('patch is damaged or loses information')) finally: os.unlink(tmpname) @@ -2772,7 +2793,9 @@ 'meaning as the corresponding patch option')), ('b', 'base', '', _('base path')), ('f', 'force', None, - _('skip check for outstanding uncommitted changes'))] + commitopts, + _('skip check for outstanding uncommitted changes')), + ('', 'exact', None, + _('apply patch to the nodes from which it was generated'))] + commitopts, _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')), "incoming|in": (incoming, [('M', 'no-merges', None, _('do not show merges')),