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 patch random signal tempfile time") |
|
13 | demandload(globals(), "fnmatch mdiff patch 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 cStringIO changegroup |
|
15 | demandload(globals(), "archival cStringIO changegroup") | |
16 | demandload(globals(), "hgweb.server sshserver") |
|
16 | demandload(globals(), "hgweb.server sshserver") | |
17 |
|
17 | |||
18 | class UnknownCommand(Exception): |
|
18 | class UnknownCommand(Exception): | |
@@ -1814,84 +1814,23 b' def import_(ui, repo, patch1, *patches, ' | |||||
1814 | d = opts["base"] |
|
1814 | d = opts["base"] | |
1815 | strip = opts["strip"] |
|
1815 | strip = opts["strip"] | |
1816 |
|
1816 | |||
1817 | mailre = re.compile(r'(?:From |[\w-]+:)') |
|
|||
1818 |
|
||||
1819 | # attempt to detect the start of a patch |
|
|||
1820 | # (this heuristic is borrowed from quilt) |
|
|||
1821 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + |
|
|||
1822 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + |
|
|||
1823 | '(---|\*\*\*)[ \t])', re.MULTILINE) |
|
|||
1824 |
|
||||
1825 | wlock = repo.wlock() |
|
1817 | wlock = repo.wlock() | |
1826 | lock = repo.lock() |
|
1818 | lock = repo.lock() | |
1827 |
|
1819 | |||
1828 | for p in patches: |
|
1820 | for p in patches: | |
1829 | pf = os.path.join(d, p) |
|
1821 | pf = os.path.join(d, p) | |
1830 |
|
1822 | |||
1831 | message = None |
|
|||
1832 | user = None |
|
|||
1833 | date = None |
|
|||
1834 | hgpatch = False |
|
|||
1835 |
|
||||
1836 | parser = email.Parser.Parser() |
|
|||
1837 | if pf == '-': |
|
1823 | if pf == '-': | |
1838 | msg = parser.parse(sys.stdin) |
|
|||
1839 | ui.status(_("applying patch from stdin\n")) |
|
1824 | ui.status(_("applying patch from stdin\n")) | |
|
1825 | tmpname, message, user, date = patch.extract(ui, sys.stdin) | |||
1840 | else: |
|
1826 | else: | |
1841 | msg = parser.parse(file(pf)) |
|
|||
1842 | ui.status(_("applying %s\n") % p) |
|
1827 | ui.status(_("applying %s\n") % p) | |
1843 |
|
1828 | tmpname, message, user, date = patch.extract(ui, file(pf)) | ||
1844 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') |
|
1829 | ||
1845 | tmpfp = os.fdopen(fd, 'w') |
|
1830 | if tmpname is None: | |
|
1831 | raise util.Abort(_('no diffs found')) | |||
|
1832 | ||||
1846 | try: |
|
1833 | try: | |
1847 | message = msg['Subject'] |
|
|||
1848 | if message: |
|
|||
1849 | message = message.replace('\n\t', ' ') |
|
|||
1850 | ui.debug('Subject: %s\n' % message) |
|
|||
1851 | user = msg['From'] |
|
|||
1852 | if user: |
|
|||
1853 | ui.debug('From: %s\n' % user) |
|
|||
1854 | diffs_seen = 0 |
|
|||
1855 | ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') |
|
|||
1856 | for part in msg.walk(): |
|
|||
1857 | content_type = part.get_content_type() |
|
|||
1858 | ui.debug('Content-Type: %s\n' % content_type) |
|
|||
1859 | if content_type not in ok_types: |
|
|||
1860 | continue |
|
|||
1861 | payload = part.get_payload(decode=True) |
|
|||
1862 | m = diffre.search(payload) |
|
|||
1863 | if m: |
|
|||
1864 | ui.debug(_('found patch at byte %d\n') % m.start(0)) |
|
|||
1865 | diffs_seen += 1 |
|
|||
1866 | hgpatch = False |
|
|||
1867 | fp = cStringIO.StringIO() |
|
|||
1868 | if message: |
|
|||
1869 | fp.write(message) |
|
|||
1870 | fp.write('\n') |
|
|||
1871 | for line in payload[:m.start(0)].splitlines(): |
|
|||
1872 | if line.startswith('# HG changeset patch'): |
|
|||
1873 | ui.debug(_('patch generated by hg export\n')) |
|
|||
1874 | hgpatch = True |
|
|||
1875 | # drop earlier commit message content |
|
|||
1876 | fp.seek(0) |
|
|||
1877 | fp.truncate() |
|
|||
1878 | elif hgpatch: |
|
|||
1879 | if line.startswith('# User '): |
|
|||
1880 | user = line[7:] |
|
|||
1881 | ui.debug('From: %s\n' % user) |
|
|||
1882 | elif line.startswith("# Date "): |
|
|||
1883 | date = line[7:] |
|
|||
1884 | if not line.startswith('# '): |
|
|||
1885 | fp.write(line) |
|
|||
1886 | fp.write('\n') |
|
|||
1887 | message = fp.getvalue() |
|
|||
1888 | if tmpfp: |
|
|||
1889 | tmpfp.write(payload) |
|
|||
1890 | if not payload.endswith('\n'): |
|
|||
1891 | tmpfp.write('\n') |
|
|||
1892 | elif not diffs_seen and message and content_type == 'text/plain': |
|
|||
1893 | message += '\n' + payload |
|
|||
1894 |
|
||||
1895 | if opts['message']: |
|
1834 | if opts['message']: | |
1896 | # pickup the cmdline msg |
|
1835 | # pickup the cmdline msg | |
1897 | message = opts['message'] |
|
1836 | message = opts['message'] | |
@@ -1903,10 +1842,6 b' def import_(ui, repo, patch1, *patches, ' | |||||
1903 | message = None |
|
1842 | message = None | |
1904 | ui.debug(_('message:\n%s\n') % message) |
|
1843 | ui.debug(_('message:\n%s\n') % message) | |
1905 |
|
1844 | |||
1906 | tmpfp.close() |
|
|||
1907 | if not diffs_seen: |
|
|||
1908 | raise util.Abort(_('no diffs found')) |
|
|||
1909 |
|
||||
1910 | files = patch.patch(strip, tmpname, ui, cwd=repo.root) |
|
1845 | files = patch.patch(strip, tmpname, ui, cwd=repo.root) | |
1911 | removes = [] |
|
1846 | removes = [] | |
1912 | if len(files) > 0: |
|
1847 | if len(files) > 0: |
@@ -6,8 +6,92 b'' | |||||
6 | # of the GNU General Public License, incorporated herein by reference. |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
7 |
|
7 | |||
8 | from demandload import demandload |
|
8 | from demandload import demandload | |
|
9 | from i18n import gettext as _ | |||
9 | demandload(globals(), "util") |
|
10 | demandload(globals(), "util") | |
10 | demandload(globals(), "os re shutil tempfile") |
|
11 | demandload(globals(), "cStringIO email.Parser os re shutil tempfile") | |
|
12 | ||||
|
13 | def extract(ui, fileobj): | |||
|
14 | '''extract patch from data read from fileobj. | |||
|
15 | ||||
|
16 | patch can be normal patch or contained in email message. | |||
|
17 | ||||
|
18 | return tuple (filename, message, user, date). any item in returned | |||
|
19 | tuple can be None. if filename is None, fileobj did not contain | |||
|
20 | patch. caller must unlink filename when done.''' | |||
|
21 | ||||
|
22 | # attempt to detect the start of a patch | |||
|
23 | # (this heuristic is borrowed from quilt) | |||
|
24 | diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' + | |||
|
25 | 'retrieving revision [0-9]+(\.[0-9]+)*$|' + | |||
|
26 | '(---|\*\*\*)[ \t])', re.MULTILINE) | |||
|
27 | ||||
|
28 | fd, tmpname = tempfile.mkstemp(prefix='hg-patch-') | |||
|
29 | tmpfp = os.fdopen(fd, 'w') | |||
|
30 | try: | |||
|
31 | hgpatch = False | |||
|
32 | ||||
|
33 | msg = email.Parser.Parser().parse(fileobj) | |||
|
34 | ||||
|
35 | message = msg['Subject'] | |||
|
36 | user = msg['From'] | |||
|
37 | # should try to parse msg['Date'] | |||
|
38 | date = None | |||
|
39 | ||||
|
40 | if message: | |||
|
41 | message = message.replace('\n\t', ' ') | |||
|
42 | ui.debug('Subject: %s\n' % message) | |||
|
43 | if user: | |||
|
44 | ui.debug('From: %s\n' % user) | |||
|
45 | diffs_seen = 0 | |||
|
46 | ok_types = ('text/plain', 'text/x-diff', 'text/x-patch') | |||
|
47 | ||||
|
48 | for part in msg.walk(): | |||
|
49 | content_type = part.get_content_type() | |||
|
50 | ui.debug('Content-Type: %s\n' % content_type) | |||
|
51 | if content_type not in ok_types: | |||
|
52 | continue | |||
|
53 | payload = part.get_payload(decode=True) | |||
|
54 | m = diffre.search(payload) | |||
|
55 | if m: | |||
|
56 | ui.debug(_('found patch at byte %d\n') % m.start(0)) | |||
|
57 | diffs_seen += 1 | |||
|
58 | cfp = cStringIO.StringIO() | |||
|
59 | if message: | |||
|
60 | cfp.write(message) | |||
|
61 | cfp.write('\n') | |||
|
62 | for line in payload[:m.start(0)].splitlines(): | |||
|
63 | if line.startswith('# HG changeset patch'): | |||
|
64 | ui.debug(_('patch generated by hg export\n')) | |||
|
65 | hgpatch = True | |||
|
66 | # drop earlier commit message content | |||
|
67 | cfp.seek(0) | |||
|
68 | cfp.truncate() | |||
|
69 | elif hgpatch: | |||
|
70 | if line.startswith('# User '): | |||
|
71 | user = line[7:] | |||
|
72 | ui.debug('From: %s\n' % user) | |||
|
73 | elif line.startswith("# Date "): | |||
|
74 | date = line[7:] | |||
|
75 | if not line.startswith('# '): | |||
|
76 | cfp.write(line) | |||
|
77 | cfp.write('\n') | |||
|
78 | message = cfp.getvalue() | |||
|
79 | if tmpfp: | |||
|
80 | tmpfp.write(payload) | |||
|
81 | if not payload.endswith('\n'): | |||
|
82 | tmpfp.write('\n') | |||
|
83 | elif not diffs_seen and message and content_type == 'text/plain': | |||
|
84 | message += '\n' + payload | |||
|
85 | except: | |||
|
86 | tmpfp.close() | |||
|
87 | os.unlink(tmpname) | |||
|
88 | raise | |||
|
89 | ||||
|
90 | tmpfp.close() | |||
|
91 | if not diffs_seen: | |||
|
92 | os.unlink(tmpname) | |||
|
93 | return None, message, user, date | |||
|
94 | return tmpname, message, user, date | |||
11 |
|
95 | |||
12 | def readgitpatch(patchname): |
|
96 | def readgitpatch(patchname): | |
13 | """extract git-style metadata about patches from <patchname>""" |
|
97 | """extract git-style metadata about patches from <patchname>""" |
General Comments 0
You need to be logged in to leave comments.
Login now