comparison mercurial/commands.py @ 2865:2893e51407a4

commands.import: refactor patch parsing into patch.extract.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Sat, 12 Aug 2006 13:16:48 -0700
parents 71e78f2ca5ae
children ffa2be02c4e5
comparison
equal deleted inserted replaced
2864:71e78f2ca5ae 2865:2893e51407a4
10 from i18n import gettext as _ 10 from i18n import gettext as _
11 demandload(globals(), "os re sys signal shutil imp urllib pdb") 11 demandload(globals(), "os re sys signal shutil imp urllib pdb")
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 email.Parser") 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):
19 """Exception raised if command is not in the command table.""" 19 """Exception raised if command is not in the command table."""
20 class AmbiguousCommand(Exception): 20 class AmbiguousCommand(Exception):
1812 bail_if_changed(repo) 1812 bail_if_changed(repo)
1813 1813
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']
1898 elif message: 1837 elif message:
1899 # pickup the patch msg 1838 # pickup the patch msg
1900 message = message.strip() 1839 message = message.strip()
1901 else: 1840 else:
1902 # launch the editor 1841 # launch the editor
1903 message = None 1842 message = None
1904 ui.debug(_('message:\n%s\n') % message) 1843 ui.debug(_('message:\n%s\n') % message)
1905
1906 tmpfp.close()
1907 if not diffs_seen:
1908 raise util.Abort(_('no diffs found'))
1909 1844
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:
1913 cfiles = files.keys() 1848 cfiles = files.keys()