Show More
@@ -1477,15 +1477,21 b' def import_(ui, repo, patch1, *patches, ' | |||
|
1477 | 1477 | text/plain body parts before first diff are added to commit |
|
1478 | 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 | 1481 | from patch override values from message headers and body. Values |
|
1482 | 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 | 1490 | To read a patch from standard input, use patch name "-". |
|
1485 | 1491 | """ |
|
1486 | 1492 | patches = (patch1,) + patches |
|
1487 | 1493 | |
|
1488 | if not opts['force']: | |
|
1494 | if opts.get('exact') or not opts['force']: | |
|
1489 | 1495 | bail_if_changed(repo) |
|
1490 | 1496 | |
|
1491 | 1497 | d = opts["base"] |
@@ -1499,10 +1505,10 b' def import_(ui, repo, patch1, *patches, ' | |||
|
1499 | 1505 | |
|
1500 | 1506 | if pf == '-': |
|
1501 | 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 | 1509 | else: |
|
1504 | 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 | 1513 | if tmpname is None: |
|
1508 | 1514 | raise util.Abort(_('no diffs found')) |
@@ -1521,12 +1527,27 b' def import_(ui, repo, patch1, *patches, ' | |||
|
1521 | 1527 | ui.debug(_('message:\n%s\n') % message) |
|
1522 | 1528 | |
|
1523 | 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 | 1541 | try: |
|
1525 | 1542 | fuzz = patch.patch(tmpname, ui, strip=strip, cwd=repo.root, |
|
1526 | 1543 | files=files) |
|
1527 | 1544 | finally: |
|
1528 | 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 | 1551 | finally: |
|
1531 | 1552 | os.unlink(tmpname) |
|
1532 | 1553 | |
@@ -2772,7 +2793,9 b' table = {' | |||
|
2772 | 2793 | 'meaning as the corresponding patch option')), |
|
2773 | 2794 | ('b', 'base', '', _('base path')), |
|
2774 | 2795 | ('f', 'force', None, |
|
2775 |
_('skip check for outstanding uncommitted changes')) |
|
|
2796 | _('skip check for outstanding uncommitted changes')), | |
|
2797 | ('', 'exact', None, | |
|
2798 | _('apply patch to the nodes from which it was generated'))] + commitopts, | |
|
2776 | 2799 | _('hg import [-p NUM] [-m MESSAGE] [-f] PATCH...')), |
|
2777 | 2800 | "incoming|in": (incoming, |
|
2778 | 2801 | [('M', 'no-merges', None, _('do not show merges')), |
@@ -33,11 +33,11 b' def copyfile(src, dst, basedir=None):' | |||
|
33 | 33 | def extract(ui, fileobj): |
|
34 | 34 | '''extract patch from data read from fileobj. |
|
35 | 35 | |
|
36 | patch can be normal patch or contained in email message. | |
|
36 | patch can be a normal patch or contained in an email message. | |
|
37 | 37 | |
|
38 |
return tuple (filename, message, user, date |
|
|
39 |
tuple can be None. |
|
|
40 |
patch. |
|
|
38 | return tuple (filename, message, user, date, node, p1, p2). | |
|
39 | Any item in the returned tuple can be None. If filename is None, | |
|
40 | fileobj did not contain a patch. Caller must unlink filename when done.''' | |
|
41 | 41 | |
|
42 | 42 | # attempt to detect the start of a patch |
|
43 | 43 | # (this heuristic is borrowed from quilt) |
@@ -54,6 +54,8 b' def extract(ui, fileobj):' | |||
|
54 | 54 | user = msg['From'] |
|
55 | 55 | # should try to parse msg['Date'] |
|
56 | 56 | date = None |
|
57 | nodeid = None | |
|
58 | parents = [] | |
|
57 | 59 | |
|
58 | 60 | if message: |
|
59 | 61 | if message.startswith('[PATCH'): |
@@ -97,6 +99,10 b' def extract(ui, fileobj):' | |||
|
97 | 99 | ui.debug('From: %s\n' % user) |
|
98 | 100 | elif line.startswith("# Date "): |
|
99 | 101 | date = line[7:] |
|
102 | elif line.startswith("# Node ID "): | |
|
103 | nodeid = line[10:] | |
|
104 | elif line.startswith("# Parent "): | |
|
105 | parents.append(line[10:]) | |
|
100 | 106 | elif line == '---' and 'git-send-email' in msg['X-Mailer']: |
|
101 | 107 | ignoretext = True |
|
102 | 108 | if not line.startswith('# ') and not ignoretext: |
@@ -117,8 +123,10 b' def extract(ui, fileobj):' | |||
|
117 | 123 | tmpfp.close() |
|
118 | 124 | if not diffs_seen: |
|
119 | 125 | os.unlink(tmpname) |
|
120 | return None, message, user, date | |
|
121 | return tmpname, message, user, date | |
|
126 | return None, message, user, date, None, None, None | |
|
127 | p1 = parents and parents.pop(0) or None | |
|
128 | p2 = parents and parents.pop(0) or None | |
|
129 | return tmpname, message, user, date, nodeid, p1, p2 | |
|
122 | 130 | |
|
123 | 131 | GP_PATCH = 1 << 0 # we have to run patch |
|
124 | 132 | GP_FILTER = 1 << 1 # there's some copy/rename operation |
General Comments 0
You need to be logged in to leave comments.
Login now