Show More
@@ -12,7 +12,7 b' demandload(globals(), "os re sys signal ' | |||||
12 | demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") |
|
12 | demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo") | |
13 | demandload(globals(), "fnmatch mdiff random signal tempfile time") |
|
13 | demandload(globals(), "fnmatch mdiff random signal tempfile time") | |
14 | demandload(globals(), "traceback errno socket version struct atexit sets bz2") |
|
14 | demandload(globals(), "traceback errno socket version struct atexit sets bz2") | |
15 | demandload(globals(), "archival changegroup") |
|
15 | demandload(globals(), "archival cStringIO changegroup email.Parser") | |
16 | demandload(globals(), "hgweb.server sshserver") |
|
16 | demandload(globals(), "hgweb.server sshserver") | |
17 |
|
17 | |||
18 | class UnknownCommand(Exception): |
|
18 | class UnknownCommand(Exception): | |
@@ -1719,11 +1719,15 b' def import_(ui, repo, patch1, *patches, ' | |||||
1719 | If there are outstanding changes in the working directory, import |
|
1719 | If there are outstanding changes in the working directory, import | |
1720 | will abort unless given the -f flag. |
|
1720 | will abort unless given the -f flag. | |
1721 |
|
1721 | |||
1722 | If a patch looks like a mail message (its first line starts with |
|
1722 | You can import a patch straight from a mail message. Even patches | |
1723 | "From " or looks like an RFC822 header), it will not be applied |
|
1723 | as attachments work (body part must be type text/plain or | |
1724 | unless the -f option is used. The importer neither parses nor |
|
1724 | text/x-patch to be used). Sender and subject line of email | |
1725 | discards mail headers, so use -f only to override the "mailness" |
|
1725 | message are used as default committer and commit message. Any | |
1726 | safety check, not to import a real mail message. |
|
1726 | text/plain body part before first diff is added to commit message. | |
|
1727 | ||||
|
1728 | If imported patch was generated by hg export, user and description | |||
|
1729 | from patch override values from message headers and body. Values | |||
|
1730 | given on command line with -m and -u override these. | |||
1727 |
|
1731 | |||
1728 | To read a patch from standard input, use patch name "-". |
|
1732 | To read a patch from standard input, use patch name "-". | |
1729 | """ |
|
1733 | """ | |
@@ -1739,79 +1743,93 b' def import_(ui, repo, patch1, *patches, ' | |||||
1739 |
|
1743 | |||
1740 | # attempt to detect the start of a patch |
|
1744 | # attempt to detect the start of a patch | |
1741 | # (this heuristic is borrowed from quilt) |
|
1745 | # (this heuristic is borrowed from quilt) | |
1742 | diffre = re.compile(r'(?:Index:[ \t]|diff[ \t]|RCS file: |' + |
|
1746 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + | |
1743 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + |
|
1747 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + | |
1744 | '(---|\*\*\*)[ \t])') |
|
1748 | '(---|\*\*\*)[ \t])', re.MULTILINE) | |
1745 |
|
1749 | |||
1746 | for patch in patches: |
|
1750 | for patch in patches: | |
1747 | pf = os.path.join(d, patch) |
|
1751 | pf = os.path.join(d, patch) | |
1748 |
|
1752 | |||
1749 |
message = |
|
1753 | message = None | |
1750 | user = None |
|
1754 | user = None | |
1751 | date = None |
|
1755 | date = None | |
1752 | hgpatch = False |
|
1756 | hgpatch = False | |
|
1757 | ||||
|
1758 | p = email.Parser.Parser() | |||
1753 | if pf == '-': |
|
1759 | if pf == '-': | |
1754 |
|
|
1760 | msg = p.parse(sys.stdin) | |
1755 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') |
|
|||
1756 | pf = tmpname |
|
|||
1757 | tmpfp = os.fdopen(fd, 'w') |
|
|||
1758 | ui.status(_("applying patch from stdin\n")) |
|
1761 | ui.status(_("applying patch from stdin\n")) | |
1759 | else: |
|
1762 | else: | |
1760 |
|
|
1763 | msg = p.parse(file(pf)) | |
1761 | tmpfp, tmpname = None, None |
|
|||
1762 | ui.status(_("applying %s\n") % patch) |
|
1764 | ui.status(_("applying %s\n") % patch) | |
|
1765 | ||||
|
1766 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') | |||
|
1767 | tmpfp = os.fdopen(fd, 'w') | |||
1763 | try: |
|
1768 | try: | |
1764 | while True: |
|
1769 | message = msg['Subject'] | |
1765 | line = f.readline() |
|
1770 | if message: | |
1766 | if not line: break |
|
1771 | message = message.replace('\n\t', ' ') | |
1767 | if tmpfp: tmpfp.write(line) |
|
1772 | ui.debug('Subject: %s\n' % message) | |
1768 | line = line.rstrip() |
|
1773 | user = msg['From'] | |
1769 | if (not message and not hgpatch and |
|
1774 | if user: | |
1770 | mailre.match(line) and not opts['force']): |
|
1775 | ui.debug('From: %s\n' % user) | |
1771 | if len(line) > 35: |
|
1776 | diffs_seen = 0 | |
1772 | line = line[:32] + '...' |
|
1777 | ok_types = ('text/plain', 'text/x-patch') | |
1773 | raise util.Abort(_('first line looks like a ' |
|
1778 | for part in msg.walk(): | |
1774 | 'mail header: ') + line) |
|
1779 | content_type = part.get_content_type() | |
1775 | if diffre.match(line): |
|
1780 | ui.debug('Content-Type: %s\n' % content_type) | |
|
1781 | if content_type not in ok_types: | |||
|
1782 | continue | |||
|
1783 | payload = part.get_payload(decode=True) | |||
|
1784 | m = diffre.search(payload) | |||
|
1785 | if m: | |||
|
1786 | ui.debug(_('found patch at byte %d\n') % m.start(0)) | |||
|
1787 | diffs_seen += 1 | |||
|
1788 | hgpatch = False | |||
|
1789 | fp = cStringIO.StringIO() | |||
|
1790 | for line in payload[:m.start(0)].splitlines(): | |||
|
1791 | if line.startswith('# HG changeset patch'): | |||
|
1792 | ui.debug(_('patch generated by hg export\n')) | |||
|
1793 | hgpatch = True | |||
|
1794 | elif hgpatch: | |||
|
1795 | if line.startswith('# User '): | |||
|
1796 | user = line[7:] | |||
|
1797 | ui.debug('From: %s\n' % user) | |||
|
1798 | elif line.startswith("# Date "): | |||
|
1799 | date = line[7:] | |||
|
1800 | if not line.startswith('# '): | |||
|
1801 | fp.write(line) | |||
|
1802 | fp.write('\n') | |||
|
1803 | hgpatch = False | |||
|
1804 | message = fp.getvalue() or message | |||
1776 | if tmpfp: |
|
1805 | if tmpfp: | |
1777 |
|
|
1806 | tmpfp.write(payload) | |
1778 |
|
|
1807 | if not payload.endswith('\n'): | |
1779 |
|
|
1808 | tmpfp.write('\n') | |
1780 | elif hgpatch: |
|
1809 | elif not diffs_seen and message and content_type == 'text/plain': | |
1781 | # parse values when importing the result of an hg export |
|
1810 | message += '\n' + payload | |
1782 | if line.startswith("# User "): |
|
|||
1783 | user = line[7:] |
|
|||
1784 | ui.debug(_('User: %s\n') % user) |
|
|||
1785 | elif line.startswith("# Date "): |
|
|||
1786 | date = line[7:] |
|
|||
1787 | elif not line.startswith("# ") and line: |
|
|||
1788 | message.append(line) |
|
|||
1789 | hgpatch = False |
|
|||
1790 | elif line == '# HG changeset patch': |
|
|||
1791 | hgpatch = True |
|
|||
1792 | message = [] # We may have collected garbage |
|
|||
1793 | elif message or line: |
|
|||
1794 | message.append(line) |
|
|||
1795 |
|
1811 | |||
1796 | if opts['message']: |
|
1812 | if opts['message']: | |
1797 | # pickup the cmdline msg |
|
1813 | # pickup the cmdline msg | |
1798 | message = opts['message'] |
|
1814 | message = opts['message'] | |
1799 | elif message: |
|
1815 | elif message: | |
1800 | # pickup the patch msg |
|
1816 | # pickup the patch msg | |
1801 |
message = |
|
1817 | message = message.strip() | |
1802 | else: |
|
1818 | else: | |
1803 | # launch the editor |
|
1819 | # launch the editor | |
1804 | message = None |
|
1820 | message = None | |
1805 | ui.debug(_('message:\n%s\n') % message) |
|
1821 | ui.debug(_('message:\n%s\n') % message) | |
1806 |
|
1822 | |||
1807 |
|
|
1823 | tmpfp.close() | |
1808 | files = util.patch(strip, pf, ui) |
|
1824 | if not diffs_seen: | |
1809 |
|
1825 | raise util.Abort(_('no diffs found')) | ||
|
1826 | ||||
|
1827 | files = util.patch(strip, tmpname, ui) | |||
1810 | if len(files) > 0: |
|
1828 | if len(files) > 0: | |
1811 | addremove_lock(ui, repo, files, {}) |
|
1829 | addremove_lock(ui, repo, files, {}) | |
1812 | repo.commit(files, message, user, date) |
|
1830 | repo.commit(files, message, user, date) | |
1813 | finally: |
|
1831 | finally: | |
1814 |
|
|
1832 | os.unlink(tmpname) | |
1815 |
|
1833 | |||
1816 | def incoming(ui, repo, source="default", **opts): |
|
1834 | def incoming(ui, repo, source="default", **opts): | |
1817 | """show new changesets found in source |
|
1835 | """show new changesets found in source |
General Comments 0
You need to be logged in to leave comments.
Login now