Mercurial > public > mercurial-scm > hg
comparison mercurial/mdiff.py @ 31271:b3861be6aa6c
mdiff: distinguish diff headers from hunks in unidiff()
Let unidiff return the list of headers it produces (lines '--- <original>' and
'+++ <new>') apart from diff hunks. In patch.diff(), we combine headers
generated there (not specific to unified format) with those from unidiff().
By returning a list of header lines, we do not append new lines in datetag
inner function of unidiff() so that all header lines are '\n'.join-ed in a
similar way.
author | Denis Laxalde <denis.laxalde@logilab.fr> |
---|---|
date | Fri, 03 Mar 2017 13:51:22 +0100 |
parents | 5e7fd3a0b17f |
children | e41946f39724 |
comparison
equal
deleted
inserted
replaced
31270:59aec562a50b | 31271:b3861be6aa6c |
---|---|
194 type = '~' | 194 type = '~' |
195 yield s, type | 195 yield s, type |
196 yield s1, '=' | 196 yield s1, '=' |
197 | 197 |
198 def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts): | 198 def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts): |
199 """Return a unified diff as a (headers, hunkstext) tuple. | |
200 | |
201 If the diff is not null, `headers` is a list with unified diff header | |
202 lines "--- <original>" and "+++ <new>" and `hunkstext` is a string | |
203 containing diff hunks. Otherwise, both `headers` and `hunkstext` are | |
204 empty. | |
205 """ | |
199 def datetag(date, fn=None): | 206 def datetag(date, fn=None): |
200 if not opts.git and not opts.nodates: | 207 if not opts.git and not opts.nodates: |
201 return '\t%s\n' % date | 208 return '\t%s' % date |
202 if fn and ' ' in fn: | 209 if fn and ' ' in fn: |
203 return '\t\n' | 210 return '\t' |
204 return '\n' | 211 return '' |
205 | 212 |
213 sentinel = [], "" | |
206 if not a and not b: | 214 if not a and not b: |
207 return "" | 215 return sentinel |
208 | 216 |
209 if opts.noprefix: | 217 if opts.noprefix: |
210 aprefix = bprefix = '' | 218 aprefix = bprefix = '' |
211 else: | 219 else: |
212 aprefix = 'a/' | 220 aprefix = 'a/' |
217 fn1 = util.pconvert(fn1) | 225 fn1 = util.pconvert(fn1) |
218 fn2 = util.pconvert(fn2) | 226 fn2 = util.pconvert(fn2) |
219 | 227 |
220 if not opts.text and (util.binary(a) or util.binary(b)): | 228 if not opts.text and (util.binary(a) or util.binary(b)): |
221 if a and b and len(a) == len(b) and a == b: | 229 if a and b and len(a) == len(b) and a == b: |
222 return "" | 230 return sentinel |
231 headerlines = [] | |
223 l = ['Binary file %s has changed\n' % fn1] | 232 l = ['Binary file %s has changed\n' % fn1] |
224 elif not a: | 233 elif not a: |
225 b = splitnewlines(b) | 234 b = splitnewlines(b) |
226 if a is None: | 235 if a is None: |
227 l1 = '--- /dev/null%s' % datetag(epoch) | 236 l1 = '--- /dev/null%s' % datetag(epoch) |
228 else: | 237 else: |
229 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) | 238 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) |
230 l2 = "+++ %s%s" % (bprefix + fn2, datetag(bd, fn2)) | 239 l2 = "+++ %s%s" % (bprefix + fn2, datetag(bd, fn2)) |
231 l3 = "@@ -0,0 +1,%d @@\n" % len(b) | 240 headerlines = [l1, l2] |
232 l = [l1, l2, l3] + ["+" + e for e in b] | 241 l = ["@@ -0,0 +1,%d @@\n" % len(b)] + ["+" + e for e in b] |
233 elif not b: | 242 elif not b: |
234 a = splitnewlines(a) | 243 a = splitnewlines(a) |
235 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) | 244 l1 = "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)) |
236 if b is None: | 245 if b is None: |
237 l2 = '+++ /dev/null%s' % datetag(epoch) | 246 l2 = '+++ /dev/null%s' % datetag(epoch) |
238 else: | 247 else: |
239 l2 = "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)) | 248 l2 = "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)) |
240 l3 = "@@ -1,%d +0,0 @@\n" % len(a) | 249 headerlines = [l1, l2] |
241 l = [l1, l2, l3] + ["-" + e for e in a] | 250 l = ["@@ -1,%d +0,0 @@\n" % len(a)] + ["-" + e for e in a] |
242 else: | 251 else: |
243 l = sum((hlines for hrange, hlines in _unidiff(a, b, opts=opts)), []) | 252 l = sum((hlines for hrange, hlines in _unidiff(a, b, opts=opts)), []) |
244 if not l: | 253 if not l: |
245 return "" | 254 return sentinel |
246 | 255 |
247 l.insert(0, "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1))) | 256 headerlines = [ |
248 l.insert(1, "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2))) | 257 "--- %s%s%s" % (aprefix, fn1, datetag(ad, fn1)), |
258 "+++ %s%s%s" % (bprefix, fn2, datetag(bd, fn2)), | |
259 ] | |
249 | 260 |
250 for ln in xrange(len(l)): | 261 for ln in xrange(len(l)): |
251 if l[ln][-1] != '\n': | 262 if l[ln][-1] != '\n': |
252 l[ln] += "\n\ No newline at end of file\n" | 263 l[ln] += "\n\ No newline at end of file\n" |
253 | 264 |
254 return "".join(l) | 265 return headerlines, "".join(l) |
255 | 266 |
256 def _unidiff(t1, t2, opts=defaultopts): | 267 def _unidiff(t1, t2, opts=defaultopts): |
257 """Yield hunks of a headerless unified diff from t1 and t2 texts. | 268 """Yield hunks of a headerless unified diff from t1 and t2 texts. |
258 | 269 |
259 Each hunk consists of a (hunkrange, hunklines) tuple where `hunkrange` is a | 270 Each hunk consists of a (hunkrange, hunklines) tuple where `hunkrange` is a |