comparison mercurial/patch.py @ 7199:dd891d0d97a3

patch: consolidate two different regexes for parsing of git diffs
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Wed, 22 Oct 2008 12:56:28 +0200
parents df79ee9b6278
children ca5ac40949dc
comparison
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('---'):