Mercurial > hg
comparison mercurial/patch.py @ 3716:ab5600428b08
handle files with both git binary patches and copy/rename ops
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Mon, 27 Nov 2006 22:03:31 -0200 |
parents | 70c3ee224c08 |
children | 9e248cfd8b94 |
comparison
equal
deleted
inserted
replaced
3715:6cb3aca69cdc | 3716:ab5600428b08 |
---|---|
112 if not diffs_seen: | 112 if not diffs_seen: |
113 os.unlink(tmpname) | 113 os.unlink(tmpname) |
114 return None, message, user, date | 114 return None, message, user, date |
115 return tmpname, message, user, date | 115 return tmpname, message, user, date |
116 | 116 |
117 GP_PATCH = 1 << 0 # we have to run patch | |
118 GP_FILTER = 1 << 1 # there's some copy/rename operation | |
119 GP_BINARY = 1 << 2 # there's a binary patch | |
120 | |
117 def readgitpatch(patchname): | 121 def readgitpatch(patchname): |
118 """extract git-style metadata about patches from <patchname>""" | 122 """extract git-style metadata about patches from <patchname>""" |
119 class gitpatch: | 123 class gitpatch: |
120 "op is one of ADD, DELETE, RENAME, MODIFY or COPY" | 124 "op is one of ADD, DELETE, RENAME, MODIFY or COPY" |
121 def __init__(self, path): | 125 def __init__(self, path): |
131 gitre = re.compile('diff --git a/(.*) b/(.*)') | 135 gitre = re.compile('diff --git a/(.*) b/(.*)') |
132 pf = file(patchname) | 136 pf = file(patchname) |
133 gp = None | 137 gp = None |
134 gitpatches = [] | 138 gitpatches = [] |
135 # Can have a git patch with only metadata, causing patch to complain | 139 # Can have a git patch with only metadata, causing patch to complain |
136 dopatch = False | 140 dopatch = 0 |
137 | 141 |
138 lineno = 0 | 142 lineno = 0 |
139 for line in pf: | 143 for line in pf: |
140 lineno += 1 | 144 lineno += 1 |
141 if line.startswith('diff --git'): | 145 if line.startswith('diff --git'): |
148 gp.lineno = lineno | 152 gp.lineno = lineno |
149 elif gp: | 153 elif gp: |
150 if line.startswith('--- '): | 154 if line.startswith('--- '): |
151 if gp.op in ('COPY', 'RENAME'): | 155 if gp.op in ('COPY', 'RENAME'): |
152 gp.copymod = True | 156 gp.copymod = True |
153 dopatch = 'filter' | 157 dopatch |= GP_FILTER |
154 gitpatches.append(gp) | 158 gitpatches.append(gp) |
155 gp = None | 159 gp = None |
156 if not dopatch: | 160 dopatch |= GP_PATCH |
157 dopatch = True | |
158 continue | 161 continue |
159 if line.startswith('rename from '): | 162 if line.startswith('rename from '): |
160 gp.op = 'RENAME' | 163 gp.op = 'RENAME' |
161 gp.oldpath = line[12:].rstrip() | 164 gp.oldpath = line[12:].rstrip() |
162 elif line.startswith('rename to '): | 165 elif line.startswith('rename to '): |
172 gp.op = 'ADD' | 175 gp.op = 'ADD' |
173 gp.mode = int(line.rstrip()[-3:], 8) | 176 gp.mode = int(line.rstrip()[-3:], 8) |
174 elif line.startswith('new mode '): | 177 elif line.startswith('new mode '): |
175 gp.mode = int(line.rstrip()[-3:], 8) | 178 gp.mode = int(line.rstrip()[-3:], 8) |
176 elif line.startswith('GIT binary patch'): | 179 elif line.startswith('GIT binary patch'): |
177 if not dopatch: | 180 dopatch |= GP_BINARY |
178 dopatch = 'binary' | |
179 gp.binary = True | 181 gp.binary = True |
180 if gp: | 182 if gp: |
181 gitpatches.append(gp) | 183 gitpatches.append(gp) |
182 | 184 |
183 if not gitpatches: | 185 if not gitpatches: |
184 dopatch = True | 186 dopatch = GP_PATCH |
185 | 187 |
186 return (dopatch, gitpatches) | 188 return (dopatch, gitpatches) |
187 | 189 |
188 def dogitpatch(patchname, gitpatches, cwd=None): | 190 def dogitpatch(patchname, gitpatches, cwd=None): |
189 """Preprocess git patch so that vanilla patch can handle it""" | 191 """Preprocess git patch so that vanilla patch can handle it""" |
310 for gp in gitpatches: | 312 for gp in gitpatches: |
311 files[gp.path] = (gp.op, gp) | 313 files[gp.path] = (gp.op, gp) |
312 | 314 |
313 fuzz = False | 315 fuzz = False |
314 if dopatch: | 316 if dopatch: |
315 if dopatch in ('filter', 'binary'): | 317 filterpatch = dopatch & (GP_FILTER | GP_BINARY) |
318 if filterpatch: | |
316 patchname = dogitpatch(patchname, gitpatches, cwd=cwd) | 319 patchname = dogitpatch(patchname, gitpatches, cwd=cwd) |
317 try: | 320 try: |
318 if dopatch != 'binary': | 321 if dopatch & GP_PATCH: |
319 fuzz = __patch(patchname) | 322 fuzz = __patch(patchname) |
320 finally: | 323 finally: |
321 if dopatch == 'filter': | 324 if filterpatch: |
322 os.unlink(patchname) | 325 os.unlink(patchname) |
323 | 326 |
324 return fuzz | 327 return fuzz |
325 | 328 |
326 def diffopts(ui, opts={}, untrusted=False): | 329 def diffopts(ui, opts={}, untrusted=False): |