2965 def isempty(fctx): |
2969 def isempty(fctx): |
2966 return fctx is None or fctx.size() == 0 |
2970 return fctx is None or fctx.size() == 0 |
2967 |
2971 |
2968 date1 = dateutil.datestr(ctx1.date()) |
2972 date1 = dateutil.datestr(ctx1.date()) |
2969 date2 = dateutil.datestr(ctx2.date()) |
2973 date2 = dateutil.datestr(ctx2.date()) |
2970 |
|
2971 gitmode = {b'l': b'120000', b'x': b'100755', b'': b'100644'} |
|
2972 |
2974 |
2973 if not pathfn: |
2975 if not pathfn: |
2974 pathfn = lambda f: f |
2976 pathfn = lambda f: f |
2975 |
2977 |
2976 for f1, f2, copyop in _filepairs(modified, added, removed, copy, opts): |
2978 for f1, f2, copyop in _filepairs(modified, added, removed, copy, opts): |
3021 if opts.git: |
3023 if opts.git: |
3022 header.append( |
3024 header.append( |
3023 b'diff --git %s%s %s%s' % (aprefix, path1, bprefix, path2) |
3025 b'diff --git %s%s %s%s' % (aprefix, path1, bprefix, path2) |
3024 ) |
3026 ) |
3025 if not f1: # added |
3027 if not f1: # added |
3026 header.append(b'new file mode %s' % gitmode[flag2]) |
3028 header.append(b'new file mode %s' % _gitmode[flag2]) |
3027 elif not f2: # removed |
3029 elif not f2: # removed |
3028 header.append(b'deleted file mode %s' % gitmode[flag1]) |
3030 header.append(b'deleted file mode %s' % _gitmode[flag1]) |
3029 else: # modified/copied/renamed |
3031 else: # modified/copied/renamed |
3030 mode1, mode2 = gitmode[flag1], gitmode[flag2] |
3032 mode1, mode2 = _gitmode[flag1], _gitmode[flag2] |
3031 if mode1 != mode2: |
3033 if mode1 != mode2: |
3032 header.append(b'old mode %s' % mode1) |
3034 header.append(b'old mode %s' % mode1) |
3033 header.append(b'new mode %s' % mode2) |
3035 header.append(b'new mode %s' % mode2) |
3034 if copyop is not None: |
3036 if copyop is not None: |
3035 if opts.showsimilarity: |
3037 if opts.showsimilarity: |
3069 if fctx1 is not None: |
3071 if fctx1 is not None: |
3070 content1 = fctx1.data() |
3072 content1 = fctx1.data() |
3071 if fctx2 is not None: |
3073 if fctx2 is not None: |
3072 content2 = fctx2.data() |
3074 content2 = fctx2.data() |
3073 |
3075 |
3074 if binary and opts.git and not opts.nobinary: |
3076 data1 = (ctx1, fctx1, path1, flag1, content1, date1) |
3075 text = mdiff.b85diff(content1, content2) |
3077 data2 = (ctx2, fctx2, path2, flag2, content2, date2) |
3076 if text: |
3078 yield diffcontent(data1, data2, header, binary, opts) |
3077 header.append( |
3079 |
3078 b'index %s..%s' % (gitindex(content1), gitindex(content2)) |
3080 |
|
3081 def diffcontent(data1, data2, header, binary, opts): |
|
3082 """ diffs two versions of a file. |
|
3083 |
|
3084 data1 and data2 are tuples containg: |
|
3085 |
|
3086 * ctx: changeset for the file |
|
3087 * fctx: file context for that file |
|
3088 * path1: name of the file |
|
3089 * flag: flags of the file |
|
3090 * content: full content of the file (can be null in case of binary) |
|
3091 * date: date of the changeset |
|
3092 |
|
3093 header: the patch header |
|
3094 binary: whether the any of the version of file is binary or not |
|
3095 opts: user passed options |
|
3096 |
|
3097 It exists as a separate function so that extensions like extdiff can wrap |
|
3098 it and use the file content directly. |
|
3099 """ |
|
3100 |
|
3101 ctx1, fctx1, path1, flag1, content1, date1 = data1 |
|
3102 ctx2, fctx2, path2, flag2, content2, date2 = data2 |
|
3103 if binary and opts.git and not opts.nobinary: |
|
3104 text = mdiff.b85diff(content1, content2) |
|
3105 if text: |
|
3106 header.append( |
|
3107 b'index %s..%s' % (_gitindex(content1), _gitindex(content2)) |
|
3108 ) |
|
3109 hunks = ((None, [text]),) |
|
3110 else: |
|
3111 if opts.git and opts.index > 0: |
|
3112 flag = flag1 |
|
3113 if flag is None: |
|
3114 flag = flag2 |
|
3115 header.append( |
|
3116 b'index %s..%s %s' |
|
3117 % ( |
|
3118 _gitindex(content1)[0 : opts.index], |
|
3119 _gitindex(content2)[0 : opts.index], |
|
3120 _gitmode[flag], |
3079 ) |
3121 ) |
3080 hunks = ((None, [text]),) |
|
3081 else: |
|
3082 if opts.git and opts.index > 0: |
|
3083 flag = flag1 |
|
3084 if flag is None: |
|
3085 flag = flag2 |
|
3086 header.append( |
|
3087 b'index %s..%s %s' |
|
3088 % ( |
|
3089 gitindex(content1)[0 : opts.index], |
|
3090 gitindex(content2)[0 : opts.index], |
|
3091 gitmode[flag], |
|
3092 ) |
|
3093 ) |
|
3094 |
|
3095 uheaders, hunks = mdiff.unidiff( |
|
3096 content1, |
|
3097 date1, |
|
3098 content2, |
|
3099 date2, |
|
3100 path1, |
|
3101 path2, |
|
3102 binary=binary, |
|
3103 opts=opts, |
|
3104 ) |
3122 ) |
3105 header.extend(uheaders) |
3123 |
3106 yield fctx1, fctx2, header, hunks |
3124 uheaders, hunks = mdiff.unidiff( |
|
3125 content1, |
|
3126 date1, |
|
3127 content2, |
|
3128 date2, |
|
3129 path1, |
|
3130 path2, |
|
3131 binary=binary, |
|
3132 opts=opts, |
|
3133 ) |
|
3134 header.extend(uheaders) |
|
3135 return fctx1, fctx2, header, hunks |
3107 |
3136 |
3108 |
3137 |
3109 def diffstatsum(stats): |
3138 def diffstatsum(stats): |
3110 maxfile, maxtotal, addtotal, removetotal, binary = 0, 0, 0, 0, False |
3139 maxfile, maxtotal, addtotal, removetotal, binary = 0, 0, 0, 0, False |
3111 for f, a, r, b in stats: |
3140 for f, a, r, b in stats: |