mercurial/patch.py
changeset 7199 dd891d0d97a3
parent 7198 df79ee9b6278
child 7200 ca5ac40949dc
equal deleted inserted replaced
7198:df79ee9b6278 7199:dd891d0d97a3
     9 from i18n import _
     9 from i18n import _
    10 from node import hex, nullid, short
    10 from node import hex, nullid, short
    11 import base85, cmdutil, mdiff, util, revlog, diffhelpers, copies
    11 import base85, cmdutil, mdiff, util, revlog, diffhelpers, copies
    12 import cStringIO, email.Parser, os, re, errno
    12 import cStringIO, email.Parser, os, re, errno
    13 import sys, tempfile, zlib
    13 import sys, tempfile, zlib
       
    14 
       
    15 gitre = re.compile('diff --git a/(.*) b/(.*)')
    14 
    16 
    15 class PatchError(Exception):
    17 class PatchError(Exception):
    16     pass
    18     pass
    17 
    19 
    18 class NoHunks(PatchError):
    20 class NoHunks(PatchError):
   168 
   170 
   169 def readgitpatch(lr):
   171 def readgitpatch(lr):
   170     """extract git-style metadata about patches from <patchname>"""
   172     """extract git-style metadata about patches from <patchname>"""
   171 
   173 
   172     # Filter patch for git information
   174     # Filter patch for git information
   173     gitre = re.compile('diff --git a/(.*) b/(.*)')
       
   174     gp = None
   175     gp = None
   175     gitpatches = []
   176     gitpatches = []
   176     # Can have a git patch with only metadata, causing patch to complain
   177     # Can have a git patch with only metadata, causing patch to complain
   177     dopatch = 0
   178     dopatch = 0
   178 
   179 
   821     afile = ""
   822     afile = ""
   822     bfile = ""
   823     bfile = ""
   823     state = None
   824     state = None
   824     hunknum = 0
   825     hunknum = 0
   825     emitfile = False
   826     emitfile = False
   826 
       
   827     git = False
   827     git = False
   828     gitre = re.compile('diff --git (a/.*) (b/.*)')
       
   829 
   828 
   830     # our states
   829     # our states
   831     BFILE = 1
   830     BFILE = 1
   832     context = None
   831     context = None
   833     lr = linereader(fp)
   832     lr = linereader(fp)
   851         if ((sourcefile or state == BFILE) and ((not context and x[0] == '@') or
   850         if ((sourcefile or state == BFILE) and ((not context and x[0] == '@') or
   852             ((context or context == None) and x.startswith('***************')))):
   851             ((context or context == None) and x.startswith('***************')))):
   853             try:
   852             try:
   854                 if context == None and x.startswith('***************'):
   853                 if context == None and x.startswith('***************'):
   855                     context = True
   854                     context = True
   856                 gpatch = changed.get(bfile[2:])
   855                 gpatch = changed.get(bfile)
   857                 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
   856                 create = afile == '/dev/null' or gpatch and gpatch.op == 'ADD'
   858                 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
   857                 remove = bfile == '/dev/null' or gpatch and gpatch.op == 'DELETE'
   859                 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
   858                 current_hunk = hunk(x, hunknum + 1, lr, context, create, remove)
   860             except PatchError, err:
   859             except PatchError, err:
   861                 ui.debug(err)
   860                 ui.debug(err)
   864             hunknum += 1
   863             hunknum += 1
   865             if emitfile:
   864             if emitfile:
   866                 emitfile = False
   865                 emitfile = False
   867                 yield 'file', (afile, bfile, current_hunk)
   866                 yield 'file', (afile, bfile, current_hunk)
   868         elif state == BFILE and x.startswith('GIT binary patch'):
   867         elif state == BFILE and x.startswith('GIT binary patch'):
   869             current_hunk = binhunk(changed[bfile[2:]])
   868             current_hunk = binhunk(changed[bfile])
   870             hunknum += 1
   869             hunknum += 1
   871             if emitfile:
   870             if emitfile:
   872                 emitfile = False
   871                 emitfile = False
   873                 yield 'file', (afile, bfile, current_hunk)
   872                 yield 'file', ('a/' + afile, 'b/' + bfile, current_hunk)
   874             current_hunk.extract(lr)
   873             current_hunk.extract(lr)
   875         elif x.startswith('diff --git'):
   874         elif x.startswith('diff --git'):
   876             # check for git diff, scanning the whole patch file if needed
   875             # check for git diff, scanning the whole patch file if needed
   877             m = gitre.match(x)
   876             m = gitre.match(x)
   878             if m:
   877             if m:
   883                     yield 'git', gitpatches
   882                     yield 'git', gitpatches
   884                     for gp in gitpatches:
   883                     for gp in gitpatches:
   885                         changed[gp.path] = gp
   884                         changed[gp.path] = gp
   886                 # else error?
   885                 # else error?
   887                 # copy/rename + modify should modify target, not source
   886                 # copy/rename + modify should modify target, not source
   888                 gp = changed.get(bfile[2:])
   887                 gp = changed.get(bfile)
   889                 if gp and gp.op in ('COPY', 'DELETE', 'RENAME'):
   888                 if gp and gp.op in ('COPY', 'DELETE', 'RENAME'):
   890                     afile = bfile
   889                     afile = bfile
   891                     gitworkdone = True
   890                     gitworkdone = True
   892             newfile = True
   891             newfile = True
   893         elif x.startswith('---'):
   892         elif x.startswith('---'):