mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 15:27:13 +03:00
commands.import: refactor patch parsing into patch.extract.
This commit is contained in:
parent
2eab8e108e
commit
beb26e5257
@ -12,7 +12,7 @@ demandload(globals(), "os re sys signal shutil imp urllib pdb")
|
||||
demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo")
|
||||
demandload(globals(), "fnmatch mdiff patch random signal tempfile time")
|
||||
demandload(globals(), "traceback errno socket version struct atexit sets bz2")
|
||||
demandload(globals(), "archival cStringIO changegroup email.Parser")
|
||||
demandload(globals(), "archival cStringIO changegroup")
|
||||
demandload(globals(), "hgweb.server sshserver")
|
||||
|
||||
class UnknownCommand(Exception):
|
||||
@ -1814,84 +1814,23 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
d = opts["base"]
|
||||
strip = opts["strip"]
|
||||
|
||||
mailre = re.compile(r'(?:From |[\w-]+:)')
|
||||
|
||||
# attempt to detect the start of a patch
|
||||
# (this heuristic is borrowed from quilt)
|
||||
diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
|
||||
'retrieving revision [0-9]+(\.[0-9]+)*$|' +
|
||||
'(---|\*\*\*)[ \t])', re.MULTILINE)
|
||||
|
||||
wlock = repo.wlock()
|
||||
lock = repo.lock()
|
||||
|
||||
for p in patches:
|
||||
pf = os.path.join(d, p)
|
||||
|
||||
message = None
|
||||
user = None
|
||||
date = None
|
||||
hgpatch = False
|
||||
|
||||
parser = email.Parser.Parser()
|
||||
if pf == '-':
|
||||
msg = parser.parse(sys.stdin)
|
||||
ui.status(_("applying patch from stdin\n"))
|
||||
tmpname, message, user, date = patch.extract(ui, sys.stdin)
|
||||
else:
|
||||
msg = parser.parse(file(pf))
|
||||
ui.status(_("applying %s\n") % p)
|
||||
tmpname, message, user, date = patch.extract(ui, file(pf))
|
||||
|
||||
if tmpname is None:
|
||||
raise util.Abort(_('no diffs found'))
|
||||
|
||||
fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
|
||||
tmpfp = os.fdopen(fd, 'w')
|
||||
try:
|
||||
message = msg['Subject']
|
||||
if message:
|
||||
message = message.replace('\n\t', ' ')
|
||||
ui.debug('Subject: %s\n' % message)
|
||||
user = msg['From']
|
||||
if user:
|
||||
ui.debug('From: %s\n' % user)
|
||||
diffs_seen = 0
|
||||
ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
|
||||
for part in msg.walk():
|
||||
content_type = part.get_content_type()
|
||||
ui.debug('Content-Type: %s\n' % content_type)
|
||||
if content_type not in ok_types:
|
||||
continue
|
||||
payload = part.get_payload(decode=True)
|
||||
m = diffre.search(payload)
|
||||
if m:
|
||||
ui.debug(_('found patch at byte %d\n') % m.start(0))
|
||||
diffs_seen += 1
|
||||
hgpatch = False
|
||||
fp = cStringIO.StringIO()
|
||||
if message:
|
||||
fp.write(message)
|
||||
fp.write('\n')
|
||||
for line in payload[:m.start(0)].splitlines():
|
||||
if line.startswith('# HG changeset patch'):
|
||||
ui.debug(_('patch generated by hg export\n'))
|
||||
hgpatch = True
|
||||
# drop earlier commit message content
|
||||
fp.seek(0)
|
||||
fp.truncate()
|
||||
elif hgpatch:
|
||||
if line.startswith('# User '):
|
||||
user = line[7:]
|
||||
ui.debug('From: %s\n' % user)
|
||||
elif line.startswith("# Date "):
|
||||
date = line[7:]
|
||||
if not line.startswith('# '):
|
||||
fp.write(line)
|
||||
fp.write('\n')
|
||||
message = fp.getvalue()
|
||||
if tmpfp:
|
||||
tmpfp.write(payload)
|
||||
if not payload.endswith('\n'):
|
||||
tmpfp.write('\n')
|
||||
elif not diffs_seen and message and content_type == 'text/plain':
|
||||
message += '\n' + payload
|
||||
|
||||
if opts['message']:
|
||||
# pickup the cmdline msg
|
||||
message = opts['message']
|
||||
@ -1903,10 +1842,6 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
message = None
|
||||
ui.debug(_('message:\n%s\n') % message)
|
||||
|
||||
tmpfp.close()
|
||||
if not diffs_seen:
|
||||
raise util.Abort(_('no diffs found'))
|
||||
|
||||
files = patch.patch(strip, tmpname, ui, cwd=repo.root)
|
||||
removes = []
|
||||
if len(files) > 0:
|
||||
|
@ -6,8 +6,92 @@
|
||||
# of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
from demandload import demandload
|
||||
from i18n import gettext as _
|
||||
demandload(globals(), "util")
|
||||
demandload(globals(), "os re shutil tempfile")
|
||||
demandload(globals(), "cStringIO email.Parser os re shutil tempfile")
|
||||
|
||||
def extract(ui, fileobj):
|
||||
'''extract patch from data read from fileobj.
|
||||
|
||||
patch can be normal patch or contained in email message.
|
||||
|
||||
return tuple (filename, message, user, date). any item in returned
|
||||
tuple can be None. if filename is None, fileobj did not contain
|
||||
patch. caller must unlink filename when done.'''
|
||||
|
||||
# attempt to detect the start of a patch
|
||||
# (this heuristic is borrowed from quilt)
|
||||
diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
|
||||
'retrieving revision [0-9]+(\.[0-9]+)*$|' +
|
||||
'(---|\*\*\*)[ \t])', re.MULTILINE)
|
||||
|
||||
fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
|
||||
tmpfp = os.fdopen(fd, 'w')
|
||||
try:
|
||||
hgpatch = False
|
||||
|
||||
msg = email.Parser.Parser().parse(fileobj)
|
||||
|
||||
message = msg['Subject']
|
||||
user = msg['From']
|
||||
# should try to parse msg['Date']
|
||||
date = None
|
||||
|
||||
if message:
|
||||
message = message.replace('\n\t', ' ')
|
||||
ui.debug('Subject: %s\n' % message)
|
||||
if user:
|
||||
ui.debug('From: %s\n' % user)
|
||||
diffs_seen = 0
|
||||
ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
|
||||
|
||||
for part in msg.walk():
|
||||
content_type = part.get_content_type()
|
||||
ui.debug('Content-Type: %s\n' % content_type)
|
||||
if content_type not in ok_types:
|
||||
continue
|
||||
payload = part.get_payload(decode=True)
|
||||
m = diffre.search(payload)
|
||||
if m:
|
||||
ui.debug(_('found patch at byte %d\n') % m.start(0))
|
||||
diffs_seen += 1
|
||||
cfp = cStringIO.StringIO()
|
||||
if message:
|
||||
cfp.write(message)
|
||||
cfp.write('\n')
|
||||
for line in payload[:m.start(0)].splitlines():
|
||||
if line.startswith('# HG changeset patch'):
|
||||
ui.debug(_('patch generated by hg export\n'))
|
||||
hgpatch = True
|
||||
# drop earlier commit message content
|
||||
cfp.seek(0)
|
||||
cfp.truncate()
|
||||
elif hgpatch:
|
||||
if line.startswith('# User '):
|
||||
user = line[7:]
|
||||
ui.debug('From: %s\n' % user)
|
||||
elif line.startswith("# Date "):
|
||||
date = line[7:]
|
||||
if not line.startswith('# '):
|
||||
cfp.write(line)
|
||||
cfp.write('\n')
|
||||
message = cfp.getvalue()
|
||||
if tmpfp:
|
||||
tmpfp.write(payload)
|
||||
if not payload.endswith('\n'):
|
||||
tmpfp.write('\n')
|
||||
elif not diffs_seen and message and content_type == 'text/plain':
|
||||
message += '\n' + payload
|
||||
except:
|
||||
tmpfp.close()
|
||||
os.unlink(tmpname)
|
||||
raise
|
||||
|
||||
tmpfp.close()
|
||||
if not diffs_seen:
|
||||
os.unlink(tmpname)
|
||||
return None, message, user, date
|
||||
return tmpname, message, user, date
|
||||
|
||||
def readgitpatch(patchname):
|
||||
"""extract git-style metadata about patches from <patchname>"""
|
||||
|
Loading…
Reference in New Issue
Block a user