30
|
30
|
|
<b>Commit</b>
|
31
|
31
|
|
</td>
|
32
|
32
|
|
<td>
|
33
|
|
- |
<a href="{{ url('commit', repository=repository[:-4], commit_id=commit.id) }}">{{ commit.id }}</a>
|
|
33
|
+ |
<a href="{{ url('commit', repository=repository[:-4], commit_id=commit.id) }}">{{ commit.short_id }}</a>
|
|
34
|
+ |
(<a href="{{ url('commit_patch', repository=repository[:-4], commit_id=commit.id, **request.query) }}">patch</a>)
|
34
|
35
|
|
</td>
|
35
|
36
|
|
</tr>
|
36
|
37
|
|
<tr>
|
38
|
39
|
|
<b>Tree</b>
|
39
|
40
|
|
</td>
|
40
|
41
|
|
<td>
|
41
|
|
- |
<a href="{{ url('tree', repository=repository[:-4], revision=commit.tree.id) }}">{{ commit.tree.id }}</a>
|
|
42
|
+ |
<a href="{{ url('tree', repository=repository[:-4], revision=commit.tree.id) }}">{{ commit.tree.short_id }}</a>
|
42
|
43
|
|
</td>
|
43
|
44
|
|
</tr>
|
44
|
45
|
|
<tr>
|
47
|
48
|
|
</td>
|
48
|
49
|
|
<td>
|
49
|
50
|
|
{% for parent in commit.parents %}
|
50
|
|
- |
<a href="{{ url('commit', repository=repository[:-4], commit_id=parent.id) }}">{{ parent.short_id }}</a>
|
|
51
|
+ |
<div>
|
|
52
|
+ |
<a href="{{ url('commit', repository=repository[:-4], commit_id=parent.id) }}">{{ parent.short_id }}</a>
|
|
53
|
+ |
(<a href="{{ url('commit2', repository=repository[:-4], commit_id=commit.id, commit_id2=parent.id) }}">diff</a>)
|
|
54
|
+ |
</div>
|
51
|
55
|
|
{% endfor %}
|
52
|
56
|
|
</td>
|
53
|
57
|
|
</tr>
|
58
|
62
|
|
|
59
|
63
|
|
<div class="message">{{ commit.message }}</div>
|
60
|
64
|
|
|
61
|
|
- |
<br /><br /><br /><br />
|
|
65
|
+ |
<br /><br />
|
62
|
66
|
|
|
63
|
|
- |
<details class="diffstat" {{ 'open' if defaults.DIFF_EXPAND_DIFFSTAT }}>
|
64
|
|
- |
{# pygit2 appears to recompute all the stats every time we use diff.stats,
|
65
|
|
- |
# therefore we set this variable in order to compute it only once.
|
66
|
|
- |
#}
|
67
|
|
- |
{% set diff_stats = diff.stats %}
|
|
67
|
+ |
<div class="separator">
|
|
68
|
+ |
commits diff:
|
|
69
|
+ |
<b>{{ commit2.short_id if commit2 else '0000000' }}</b>..<b>{{ commit.short_id }}</b>
|
|
70
|
+ |
</div>
|
|
71
|
+ |
|
|
72
|
+ |
{# pygit2 appears to recompute all the stats every time we use diff.stats,
|
|
73
|
+ |
# therefore we set this variable in order to compute it only once.
|
|
74
|
+ |
#}
|
|
75
|
+ |
{% set diff_stats = diff.stats %}
|
|
76
|
+ |
|
|
77
|
+ |
<div class="accumulated">
|
|
78
|
+ |
<b>{{ diff_stats.files_changed }}</b> file{{ 's' if diff_stats.files_changed != 1 }} changed,
|
|
79
|
+ |
<span class="insertions"><b>{{ diff_stats.insertions }}</b> insertion{{ 's' if diff_stats.insertions != 1 }}</span>,
|
|
80
|
+ |
<span class="deletions"><b>{{ diff_stats.deletions }}</b> deletion{{ 's' if diff_stats.deletions != 1 }}</span>
|
|
81
|
+ |
—
|
|
82
|
+ |
{% if commit2 %}
|
|
83
|
+ |
<a href="{{ url('commit_diff2', repository=repository[:-4], commit_id=commit.id, commit_id2=commit2.id, **request.query) }}">download</a>
|
|
84
|
+ |
{% else %}
|
|
85
|
+ |
<a href="{{ url('commit_diff', repository=repository[:-4], commit_id=commit.id, **request.query) }}">download</a>
|
|
86
|
+ |
{% endif %}
|
|
87
|
+ |
</div>
|
|
88
|
+ |
|
|
89
|
+ |
<br /><br />
|
68
|
90
|
|
|
|
91
|
+ |
<details class="diffstat" {{ 'open' if defaults.DIFF_EXPAND_DIFFSTAT }}>
|
69
|
92
|
|
<summary>Diffstat</summary>
|
70
|
93
|
|
<table>
|
71
|
94
|
|
{% for patch in diff %}
|
85
|
108
|
|
</tr>
|
86
|
109
|
|
{% endfor %}
|
87
|
110
|
|
</table>
|
88
|
|
- |
|
89
|
|
- |
<div class="accumulated">
|
90
|
|
- |
<b>{{ diff_stats.files_changed }}</b> file{{ 's' if diff_stats.files_changed != 1 }} changed,
|
91
|
|
- |
<span class="insertions"><b>{{ diff_stats.insertions }}</b> insertion{{ 's' if diff_stats.insertions != 1 }}</span>,
|
92
|
|
- |
<span class="deletions"><b>{{ diff_stats.deletions }}</b> deletion{{ 's' if diff_stats.deletions != 1 }}</span>
|
93
|
|
- |
</div>
|
94
|
111
|
|
</details>
|
95
|
112
|
|
|
96
|
113
|
|
<br />
|
111
|
128
|
|
</tr>
|
112
|
129
|
|
<tr>
|
113
|
130
|
|
<td>
|
114
|
|
- |
Context lines
|
|
131
|
+ |
Side
|
115
|
132
|
|
</td>
|
116
|
133
|
|
<td>
|
117
|
|
- |
<input type="number" min=0 max=1000 name="context_lines" value="{{ context_lines }}" />
|
|
134
|
+ |
<label><input type="radio" name="side" value="normal" {{ 'checked' if side == 'normal' }}>Normal</label>
|
|
135
|
+ |
<label><input type="radio" name="side" value="reverse" {{ 'checked' if side == 'reverse' }}>Reverse</label>
|
118
|
136
|
|
</td>
|
119
|
137
|
|
</tr>
|
120
|
138
|
|
<tr>
|
121
|
139
|
|
<td>
|
122
|
|
- |
Inter-hunk lines
|
|
140
|
+ |
Whitespace
|
123
|
141
|
|
</td>
|
124
|
142
|
|
<td>
|
125
|
|
- |
<input type="number" min=0 max=1000 name="inter_hunk_lines" value="{{ inter_hunk_lines }}" />
|
|
143
|
+ |
<label><input type="radio" name="whitespace" value="include" {{ 'checked' if whitespace == 'include' }}>Include</label>
|
|
144
|
+ |
<label><input type="radio" name="whitespace" value="ignore_all" {{ 'checked' if whitespace == 'ignore_all' }}>Ignore all</label>
|
|
145
|
+ |
<label><input type="radio" name="whitespace" value="ignore_change" {{ 'checked' if whitespace == 'ignore_change' }}>Ignore amount changes</label>
|
|
146
|
+ |
<label><input type="radio" name="whitespace" value="ignore_eol" {{ 'checked' if whitespace == 'ignore_eol' }}>Ignore at end of line</label>
|
126
|
147
|
|
</td>
|
127
|
148
|
|
</tr>
|
128
|
149
|
|
<tr>
|
129
|
150
|
|
<td>
|
130
|
|
- |
Side
|
|
151
|
+ |
Context lines
|
131
|
152
|
|
</td>
|
132
|
153
|
|
<td>
|
133
|
|
- |
<label><input type="radio" name="side" value="normal" {{ 'checked' if side == 'normal' }}>Normal</label>
|
134
|
|
- |
<label><input type="radio" name="side" value="reverse" {{ 'checked' if side == 'reverse' }}>Reverse</label>
|
|
154
|
+ |
<input type="number" min=0 max=1000 name="context_lines" value="{{ context_lines }}" />
|
135
|
155
|
|
</td>
|
136
|
156
|
|
</tr>
|
137
|
157
|
|
<tr>
|
138
|
158
|
|
<td>
|
139
|
|
- |
Whitespace
|
|
159
|
+ |
Inter-hunk lines
|
140
|
160
|
|
</td>
|
141
|
161
|
|
<td>
|
142
|
|
- |
<label><input type="radio" name="whitespace" value="include" {{ 'checked' if whitespace == 'include' }}>Include</label>
|
143
|
|
- |
<label><input type="radio" name="whitespace" value="ignore_all" {{ 'checked' if whitespace == 'ignore_all' }}>Ignore all</label>
|
144
|
|
- |
<label><input type="radio" name="whitespace" value="ignore_change" {{ 'checked' if whitespace == 'ignore_change' }}>Ignore amount changes</label>
|
145
|
|
- |
<label><input type="radio" name="whitespace" value="ignore_eol" {{ 'checked' if whitespace == 'ignore_eol' }}>Ignore at end of line</label>
|
|
162
|
+ |
<input type="number" min=0 max=1000 name="inter_hunk_lines" value="{{ inter_hunk_lines }}" />
|
146
|
163
|
|
</td>
|
147
|
164
|
|
</tr>
|
148
|
165
|
|
</table>
|
151
|
168
|
|
</details>
|
152
|
169
|
|
|
153
|
170
|
|
{% if mode == 'udiff_raw' %}
|
154
|
|
- |
|
|
171
|
+ |
|
155
|
172
|
|
<div class="raw_diff">{{ diff.patch|highlight_udiff|safe }}</div>
|
156
|
173
|
|
|
157
|
174
|
|
{% else %}
|
158
|
|
- |
|
159
|
|
- |
{% for patch in diff %}
|
160
|
|
- |
|
161
|
|
- |
{# The following status values are defined in the git_delta_t enum
|
162
|
|
- |
# in libgit2. See https://github.com/libgit2/libgit2/blob/main/include/git2/diff.h
|
163
|
|
- |
# Looks like pygit2 also has a pygit2.DiffDelta.status_char() functions that
|
164
|
|
- |
# returns the single-char abbreviation of the delta status, so we can use this
|
165
|
|
- |
# instead of the raw integer.
|
166
|
|
- |
# 0 = UNCHANGED
|
167
|
|
- |
# 1 = ADDED (does not exist in old version)
|
168
|
|
- |
# 2 = DELETED (does not exist in new version)
|
169
|
|
- |
# 3 = MODIFIED (content changed between old and new versions)
|
170
|
|
- |
# 4 = RENAMED
|
171
|
|
- |
# 5 = COPIED
|
172
|
|
- |
# ... (there are other codes that we don't use)
|
173
|
|
- |
#}
|
174
|
175
|
|
|
175
|
|
- |
{% set delta_char = patch.delta.status_char() %}
|
176
|
|
- |
|
177
|
|
- |
<details class="diff_view" id="{{ (patch.delta.new_file.id|string)[:7] }}" {{ 'open' if defaults.DIFF_EXPAND }}>
|
178
|
|
- |
|
179
|
|
- |
<summary>
|
180
|
|
- |
{% if patch.line_stats[1] + patch.line_stats[2] > 0 %}
|
181
|
|
- |
{% set color_border = patch.line_stats[1] / ( patch.line_stats[1] + patch.line_stats[2] ) * 100 %}
|
182
|
|
- |
{% else %}
|
183
|
|
- |
{% set color_border = 0 %}
|
184
|
|
- |
{% endif %}
|
185
|
|
- |
|
186
|
|
- |
<span class="histogram" style="border-image: linear-gradient(to right, lightgreen {{ color_border }}%, red {{ color_border }}%) 1;">
|
187
|
|
- |
+{{ patch.line_stats[1] }}/-{{ patch.line_stats[2] }}
|
188
|
|
- |
</span>
|
189
|
|
- |
|
190
|
|
- |
{% if delta_char == 'A' %}
|
191
|
|
- |
<b title="Added">A</b> {{ patch.delta.new_file.path }}
|
192
|
|
- |
{% endif %}
|
193
|
|
- |
|
194
|
|
- |
{% if delta_char == 'D' %}
|
195
|
|
- |
<b title="Deleted">D</b> {{ patch.delta.old_file.path }}
|
196
|
|
- |
{% endif %}
|
197
|
|
- |
|
198
|
|
- |
{% if delta_char == 'M' %}
|
199
|
|
- |
<b title="Modified">M</b> {{ patch.delta.new_file.path }}
|
200
|
|
- |
{% endif %}
|
201
|
|
- |
|
202
|
|
- |
{% if delta_char == 'R' %}
|
203
|
|
- |
<b title="Renamed">R</b> {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
|
204
|
|
- |
{% endif %}
|
205
|
|
- |
|
206
|
|
- |
{% if delta_char == 'C' %}
|
207
|
|
- |
<b title="Copied">C</b> {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
|
208
|
|
- |
{% endif %}
|
209
|
|
- |
|
210
|
|
- |
<table>
|
211
|
|
- |
<tr>
|
212
|
|
- |
<td>
|
213
|
|
- |
index <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}">{{ (patch.delta.old_file.id|string)[:7] }}</a>..<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}">{{ (patch.delta.new_file.id|string)[:7] }}</a>
|
214
|
|
- |
</td>
|
215
|
|
- |
</tr>
|
216
|
|
- |
<tr>
|
217
|
|
- |
<td colspan="4">
|
218
|
|
- |
old size: {{ patch.delta.old_file.size|human_size(B=true) }}
|
219
|
|
- |
-
|
220
|
|
- |
new size: {{ patch.delta.new_file.size|human_size(B=true) }}
|
221
|
|
- |
</td>
|
222
|
|
- |
</tr>
|
223
|
|
- |
<tr>
|
224
|
|
- |
<td colspan="4">
|
225
|
|
- |
{% if delta_char == 'A' %}
|
226
|
|
- |
new file mode: {{ patch.delta.new_file.mode|filemode }}
|
227
|
|
- |
{% elif delta_char == 'D' %}
|
228
|
|
- |
deleted file mode: {{ patch.delta.old_file.mode|filemode }}
|
229
|
|
- |
{% elif patch.delta.old_file.mode != patch.delta.new_file.mode %}
|
230
|
|
- |
old mode: {{ patch.delta.old_file.mode|filemode }}
|
231
|
|
- |
<br />
|
232
|
|
- |
new mode: {{ patch.delta.new_file.mode|filemode }}
|
233
|
|
- |
{% endif %}
|
234
|
|
- |
</td>
|
235
|
|
- |
</tr>
|
236
|
|
- |
</table>
|
237
|
|
- |
</summary>
|
238
|
|
- |
|
239
|
|
- |
<table class="diff">
|
240
|
|
- |
{% if patch.delta.is_binary %}
|
241
|
|
- |
<tr>
|
242
|
|
- |
<td colspan="4">
|
243
|
|
- |
<i>Binary file</i>
|
244
|
|
- |
</td>
|
245
|
|
- |
</tr>
|
246
|
|
- |
{% endif %}
|
247
|
|
- |
|
248
|
|
- |
{% for hunk in patch.hunks if not patch.delta.is_binary %}
|
|
176
|
+ |
{% for patch in diff %}
|
|
177
|
+ |
|
|
178
|
+ |
{# The following status values are defined in the git_delta_t enum
|
|
179
|
+ |
# in libgit2. See https://github.com/libgit2/libgit2/blob/main/include/git2/diff.h
|
|
180
|
+ |
# Looks like pygit2 also has a pygit2.DiffDelta.status_char() functions that
|
|
181
|
+ |
# returns the single-char abbreviation of the delta status, so we can use this
|
|
182
|
+ |
# instead of the raw integer.
|
|
183
|
+ |
# 0 = UNCHANGED
|
|
184
|
+ |
# 1 = ADDED (does not exist in old version)
|
|
185
|
+ |
# 2 = DELETED (does not exist in new version)
|
|
186
|
+ |
# 3 = MODIFIED (content changed between old and new versions)
|
|
187
|
+ |
# 4 = RENAMED
|
|
188
|
+ |
# 5 = COPIED
|
|
189
|
+ |
# ... (there are other codes that we don't use)
|
|
190
|
+ |
#}
|
|
191
|
+ |
|
|
192
|
+ |
{% set delta_char = patch.delta.status_char() %}
|
|
193
|
+ |
|
|
194
|
+ |
<details class="diff_view" id="{{ (patch.delta.new_file.id|string)[:7] }}" {{ 'open' if defaults.DIFF_EXPAND }}>
|
|
195
|
+ |
|
|
196
|
+ |
<summary>
|
|
197
|
+ |
{% if patch.line_stats[1] + patch.line_stats[2] > 0 %}
|
|
198
|
+ |
{% set color_border = patch.line_stats[1] / ( patch.line_stats[1] + patch.line_stats[2] ) * 100 %}
|
|
199
|
+ |
{% else %}
|
|
200
|
+ |
{% set color_border = 0 %}
|
|
201
|
+ |
{% endif %}
|
249
|
202
|
|
|
250
|
|
- |
{#### UDIFF mode ####}
|
251
|
|
- |
{# In this mode the lines are printed one after the other. #}
|
|
203
|
+ |
<span class="histogram" style="border-image: linear-gradient(to right, lightgreen {{ color_border }}%, red {{ color_border }}%) 1;">
|
|
204
|
+ |
+{{ patch.line_stats[1] }}/-{{ patch.line_stats[2] }}
|
|
205
|
+ |
</span>
|
252
|
206
|
|
|
253
|
|
- |
{% if mode == 'udiff' %}
|
254
|
|
- |
<tr class="header">
|
255
|
|
- |
<td></td>
|
256
|
|
- |
<td></td>
|
257
|
|
- |
<td></td>
|
258
|
|
- |
<td>{{ hunk.header }}</td>
|
259
|
|
- |
</tr>
|
260
|
|
- |
|
261
|
|
- |
{% for line in hunk.lines %}
|
262
|
|
- |
<tr class="udiff {{ 'insertion' if line.old_lineno < 0 }} {{ 'deletion' if line.new_lineno < 0 }}">
|
263
|
|
- |
<td class="linenos">
|
264
|
|
- |
{% if line.old_lineno >= 0 %}
|
265
|
|
- |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}#line-{{ line.old_lineno }}">{{ line.old_lineno }}</a>
|
266
|
|
- |
{% endif %}
|
267
|
|
- |
</td>
|
268
|
|
- |
<td class="linenos">
|
269
|
|
- |
{% if line.new_lineno >= 0 %}
|
270
|
|
- |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ line.new_lineno }}">{{ line.new_lineno }}</a>
|
271
|
|
- |
{% endif %}
|
272
|
|
- |
</td>
|
273
|
|
- |
<td class="origin">{{ line.origin }}</td>
|
274
|
|
- |
<td class="content">{{ line.content }}</td>
|
275
|
|
- |
</tr>
|
276
|
|
- |
{% endfor %}
|
|
207
|
+ |
{% if delta_char == 'A' %}
|
|
208
|
+ |
<b title="Added">A</b> {{ patch.delta.new_file.path }}
|
277
|
209
|
|
{% endif %}
|
278
|
210
|
|
|
279
|
|
- |
{#### SSDIFF mode ####}
|
280
|
|
- |
{# In this mode, changed lines are buffered until we find an
|
281
|
|
- |
# unchanged line. When an unchanged line has been found, the
|
282
|
|
- |
# buffer is emptied.
|
283
|
|
- |
#}
|
|
211
|
+ |
{% if delta_char == 'D' %}
|
|
212
|
+ |
<b title="Deleted">D</b> {{ patch.delta.old_file.path }}
|
|
213
|
+ |
{% endif %}
|
284
|
214
|
|
|
285
|
|
- |
{% if mode == 'ssdiff' %}
|
286
|
|
- |
{% set buffer_deletions = [] %}
|
287
|
|
- |
{% set buffer_insertions = [] %}
|
288
|
|
- |
|
289
|
|
- |
{% macro print_buffer(buffer_deletions, buffer_insertions) %}
|
290
|
|
- |
{% for buffer_del, buffer_ins in zip_longest(buffer_deletions, buffer_insertions) %}
|
291
|
|
- |
<tr class="ssdiff">
|
292
|
|
- |
{% if buffer_del %}
|
293
|
|
- |
<td class="linenos">
|
294
|
|
- |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}#line-{{ buffer_del.old_lineno }}">{{ buffer_del.old_lineno }}</a>
|
295
|
|
- |
</td>
|
296
|
|
- |
<td class="content {{ 'deletion' if buffer_insertions|length == 0 else 'change' }}">{{ buffer_del.content }}</td>
|
297
|
|
- |
{% else %}
|
298
|
|
- |
<td class="linenos">
|
299
|
|
- |
</td>
|
300
|
|
- |
<td class="content"></td>
|
301
|
|
- |
{% endif %}
|
302
|
|
- |
|
303
|
|
- |
{% if buffer_ins %}
|
304
|
|
- |
<td class="linenos">
|
305
|
|
- |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ buffer_ins.new_lineno }}">{{ buffer_ins.new_lineno }}</a>
|
306
|
|
- |
</td>
|
307
|
|
- |
<td class="content {{ 'insertion' if buffer_deletions|length == 0 else 'change' }}">{{ buffer_ins.content }}</td>
|
308
|
|
- |
{% else %}
|
309
|
|
- |
<td class="linenos">
|
310
|
|
- |
</td>
|
311
|
|
- |
<td class="content"></td>
|
312
|
|
- |
{% endif %}
|
313
|
|
- |
</tr>
|
314
|
|
- |
{% endfor %}
|
315
|
|
- |
|
316
|
|
- |
{# .clear() empties the buffer. Since this requires {{}}
|
317
|
|
- |
# brackets instead of {%%}, this line will print the value
|
318
|
|
- |
# of "buffer_deletions" which is "None".
|
319
|
|
- |
# "or ''" is a hack for printing an empty line instead of "None".
|
320
|
|
- |
#}
|
321
|
|
- |
{{ buffer_deletions.clear() or '' }}
|
322
|
|
- |
{{ buffer_insertions.clear() or '' }}
|
323
|
|
- |
{% endmacro %}
|
324
|
|
- |
|
325
|
|
- |
<tr class="header">
|
326
|
|
- |
<td colspan=4>{{ hunk.header }}</td>
|
|
215
|
+ |
{% if delta_char == 'M' %}
|
|
216
|
+ |
<b title="Modified">M</b> {{ patch.delta.new_file.path }}
|
|
217
|
+ |
{% endif %}
|
|
218
|
+ |
|
|
219
|
+ |
{% if delta_char == 'R' %}
|
|
220
|
+ |
<b title="Renamed">R</b> {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
|
|
221
|
+ |
{% endif %}
|
|
222
|
+ |
|
|
223
|
+ |
{% if delta_char == 'C' %}
|
|
224
|
+ |
<b title="Copied">C</b> {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
|
|
225
|
+ |
{% endif %}
|
|
226
|
+ |
|
|
227
|
+ |
<table>
|
|
228
|
+ |
<tr>
|
|
229
|
+ |
<td>
|
|
230
|
+ |
index
|
|
231
|
+ |
{% if delta_char == 'A' %}
|
|
232
|
+ |
{{ (patch.delta.old_file.id|string)[:7] }}
|
|
233
|
+ |
{%- else -%}
|
|
234
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit2.id, tree_path=patch.delta.old_file.path) }}">{{ (patch.delta.old_file.id|string)[:7] }}</a>
|
|
235
|
+ |
{%- endif -%}
|
|
236
|
+ |
..
|
|
237
|
+ |
{%- if delta_char == 'D' -%}
|
|
238
|
+ |
{{ (patch.delta.new_file.id|string)[:7] }}
|
|
239
|
+ |
{%- else -%}
|
|
240
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}">{{ (patch.delta.new_file.id|string)[:7] }}</a>
|
|
241
|
+ |
{% endif %}
|
|
242
|
+ |
</td>
|
|
243
|
+ |
</tr>
|
|
244
|
+ |
<tr>
|
|
245
|
+ |
<td colspan="4">
|
|
246
|
+ |
old size: {{ patch.delta.old_file.size|human_size(B=true) }}
|
|
247
|
+ |
-
|
|
248
|
+ |
new size: {{ patch.delta.new_file.size|human_size(B=true) }}
|
|
249
|
+ |
</td>
|
|
250
|
+ |
</tr>
|
|
251
|
+ |
<tr>
|
|
252
|
+ |
<td colspan="4">
|
|
253
|
+ |
{% if delta_char == 'A' %}
|
|
254
|
+ |
new file mode: {{ patch.delta.new_file.mode|filemode }}
|
|
255
|
+ |
{% elif delta_char == 'D' %}
|
|
256
|
+ |
deleted file mode: {{ patch.delta.old_file.mode|filemode }}
|
|
257
|
+ |
{% elif patch.delta.old_file.mode != patch.delta.new_file.mode %}
|
|
258
|
+ |
old mode: {{ patch.delta.old_file.mode|filemode }}
|
|
259
|
+ |
<br />
|
|
260
|
+ |
new mode: {{ patch.delta.new_file.mode|filemode }}
|
|
261
|
+ |
{% endif %}
|
|
262
|
+ |
</td>
|
327
|
263
|
|
</tr>
|
|
264
|
+ |
</table>
|
|
265
|
+ |
</summary>
|
|
266
|
+ |
|
|
267
|
+ |
<table class="diff">
|
|
268
|
+ |
{% if patch.delta.is_binary %}
|
|
269
|
+ |
<tr>
|
|
270
|
+ |
<td colspan="4">
|
|
271
|
+ |
<i>Binary file</i>
|
|
272
|
+ |
</td>
|
|
273
|
+ |
</tr>
|
|
274
|
+ |
{% endif %}
|
|
275
|
+ |
|
|
276
|
+ |
{% for hunk in patch.hunks if not patch.delta.is_binary %}
|
328
|
277
|
|
|
329
|
|
- |
{% for line in hunk.lines %}
|
330
|
|
- |
{% if line.old_lineno < 0 %}
|
331
|
|
- |
{{ buffer_insertions.append(line) or '' }}
|
332
|
|
- |
{% endif %}
|
333
|
|
- |
|
334
|
|
- |
{% if line.new_lineno < 0 %}
|
335
|
|
- |
{{ buffer_deletions.append(line) or '' }}
|
336
|
|
- |
{% endif %}
|
337
|
|
- |
|
338
|
|
- |
{% if line.old_lineno >= 0 and line.new_lineno >= 0 %}
|
|
278
|
+ |
{#### UDIFF mode ####}
|
|
279
|
+ |
{# In this mode the lines are printed one after the other. #}
|
|
280
|
+ |
|
|
281
|
+ |
{% if mode == 'udiff' %}
|
|
282
|
+ |
<tr class="header">
|
|
283
|
+ |
<td></td>
|
|
284
|
+ |
<td></td>
|
|
285
|
+ |
<td></td>
|
|
286
|
+ |
<td>{{ hunk.header }}</td>
|
|
287
|
+ |
</tr>
|
339
|
288
|
|
|
340
|
|
- |
{# Unload buffer #}
|
341
|
|
- |
{{ print_buffer(buffer_deletions, buffer_insertions) }}
|
342
|
|
- |
|
343
|
|
- |
{# Insert the unchanged line. #}
|
344
|
|
- |
<tr class="ssdiff">
|
|
289
|
+ |
{% for line in hunk.lines %}
|
|
290
|
+ |
<tr class="udiff {{ 'insertion' if line.old_lineno < 0 }} {{ 'deletion' if line.new_lineno < 0 }}">
|
345
|
291
|
|
<td class="linenos">
|
346
|
|
- |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}#line-{{ line.old_lineno }}">{{ line.old_lineno }}</a>
|
|
292
|
+ |
{% if line.old_lineno >= 0 %}
|
|
293
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit2.id, tree_path=patch.delta.old_file.path) }}#line-{{ line.old_lineno }}">{{ line.old_lineno }}</a>
|
|
294
|
+ |
{% endif %}
|
347
|
295
|
|
</td>
|
348
|
|
- |
<td class="content">{{ line.content }}</td>
|
349
|
|
- |
|
350
|
296
|
|
<td class="linenos">
|
351
|
|
- |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ line.new_lineno }}">{{ line.new_lineno }}</a>
|
|
297
|
+ |
{% if line.new_lineno >= 0 %}
|
|
298
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ line.new_lineno }}">{{ line.new_lineno }}</a>
|
|
299
|
+ |
{% endif %}
|
352
|
300
|
|
</td>
|
|
301
|
+ |
<td class="origin">{{ line.origin }}</td>
|
353
|
302
|
|
<td class="content">{{ line.content }}</td>
|
354
|
303
|
|
</tr>
|
355
|
|
- |
{% endif %}
|
356
|
|
- |
{% endfor %}
|
|
304
|
+ |
{% endfor %}
|
|
305
|
+ |
{% endif %}
|
357
|
306
|
|
|
358
|
|
- |
{# Empty remaining buffer. There is a non-empty buffer if we did
|
359
|
|
- |
# not find an unchanged line, for example when context_lines=0.
|
|
307
|
+ |
{#### SSDIFF mode ####}
|
|
308
|
+ |
{# In this mode, changed lines are buffered until we find an
|
|
309
|
+ |
# unchanged line. When an unchanged line has been found, the
|
|
310
|
+ |
# buffer is emptied.
|
360
|
311
|
|
#}
|
361
|
|
- |
{{ print_buffer(buffer_deletions, buffer_insertions) }}
|
362
|
|
- |
{% endif %}
|
363
|
|
- |
|
364
|
|
- |
{% endfor %}
|
365
|
|
- |
|
366
|
|
- |
</table>
|
367
|
|
- |
</details>
|
|
312
|
+ |
|
|
313
|
+ |
{% if mode == 'ssdiff' %}
|
|
314
|
+ |
{% set buffer_deletions = [] %}
|
|
315
|
+ |
{% set buffer_insertions = [] %}
|
|
316
|
+ |
|
|
317
|
+ |
{% macro print_buffer(buffer_deletions, buffer_insertions) %}
|
|
318
|
+ |
{% for buffer_del, buffer_ins in zip_longest(buffer_deletions, buffer_insertions) %}
|
|
319
|
+ |
<tr class="ssdiff">
|
|
320
|
+ |
{% if buffer_del %}
|
|
321
|
+ |
<td class="linenos">
|
|
322
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit2.id, tree_path=patch.delta.old_file.path) }}#line-{{ buffer_del.old_lineno }}">{{ buffer_del.old_lineno }}</a>
|
|
323
|
+ |
</td>
|
|
324
|
+ |
<td class="content {{ 'deletion' if buffer_insertions|length == 0 else 'change' }}">{{ buffer_del.content }}</td>
|
|
325
|
+ |
{% else %}
|
|
326
|
+ |
<td class="linenos">
|
|
327
|
+ |
</td>
|
|
328
|
+ |
<td class="content"></td>
|
|
329
|
+ |
{% endif %}
|
|
330
|
+ |
|
|
331
|
+ |
{% if buffer_ins %}
|
|
332
|
+ |
<td class="linenos">
|
|
333
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ buffer_ins.new_lineno }}">{{ buffer_ins.new_lineno }}</a>
|
|
334
|
+ |
</td>
|
|
335
|
+ |
<td class="content {{ 'insertion' if buffer_deletions|length == 0 else 'change' }}">{{ buffer_ins.content }}</td>
|
|
336
|
+ |
{% else %}
|
|
337
|
+ |
<td class="linenos">
|
|
338
|
+ |
</td>
|
|
339
|
+ |
<td class="content"></td>
|
|
340
|
+ |
{% endif %}
|
|
341
|
+ |
</tr>
|
|
342
|
+ |
{% endfor %}
|
|
343
|
+ |
|
|
344
|
+ |
{# .clear() empties the buffer. Since this requires {{}}
|
|
345
|
+ |
# brackets instead of {%%}, this line will print the value
|
|
346
|
+ |
# of "buffer_deletions" which is "None".
|
|
347
|
+ |
# "or ''" is a hack for printing an empty line instead of "None".
|
|
348
|
+ |
#}
|
|
349
|
+ |
{{ buffer_deletions.clear() or '' }}
|
|
350
|
+ |
{{ buffer_insertions.clear() or '' }}
|
|
351
|
+ |
{% endmacro %}
|
|
352
|
+ |
|
|
353
|
+ |
<tr class="header">
|
|
354
|
+ |
<td colspan=4>{{ hunk.header }}</td>
|
|
355
|
+ |
</tr>
|
|
356
|
+ |
|
|
357
|
+ |
{% for line in hunk.lines %}
|
|
358
|
+ |
{% if line.old_lineno < 0 %}
|
|
359
|
+ |
{{ buffer_insertions.append(line) or '' }}
|
|
360
|
+ |
{% endif %}
|
|
361
|
+ |
|
|
362
|
+ |
{% if line.new_lineno < 0 %}
|
|
363
|
+ |
{{ buffer_deletions.append(line) or '' }}
|
|
364
|
+ |
{% endif %}
|
|
365
|
+ |
|
|
366
|
+ |
{% if line.old_lineno >= 0 and line.new_lineno >= 0 %}
|
|
367
|
+ |
|
|
368
|
+ |
{# Unload buffer #}
|
|
369
|
+ |
{{ print_buffer(buffer_deletions, buffer_insertions) }}
|
|
370
|
+ |
|
|
371
|
+ |
{# Insert the unchanged line. #}
|
|
372
|
+ |
<tr class="ssdiff">
|
|
373
|
+ |
<td class="linenos">
|
|
374
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit2.id, tree_path=patch.delta.old_file.path) }}#line-{{ line.old_lineno }}">{{ line.old_lineno }}</a>
|
|
375
|
+ |
</td>
|
|
376
|
+ |
<td class="content">{{ line.content }}</td>
|
|
377
|
+ |
|
|
378
|
+ |
<td class="linenos">
|
|
379
|
+ |
<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ line.new_lineno }}">{{ line.new_lineno }}</a>
|
|
380
|
+ |
</td>
|
|
381
|
+ |
<td class="content">{{ line.content }}</td>
|
|
382
|
+ |
</tr>
|
|
383
|
+ |
{% endif %}
|
|
384
|
+ |
{% endfor %}
|
|
385
|
+ |
|
|
386
|
+ |
{# Empty remaining buffer. There is a non-empty buffer if we did
|
|
387
|
+ |
# not find an unchanged line, for example when context_lines=0.
|
|
388
|
+ |
#}
|
|
389
|
+ |
{{ print_buffer(buffer_deletions, buffer_insertions) }}
|
|
390
|
+ |
{% endif %}
|
|
391
|
+ |
|
|
392
|
+ |
{% endfor %}
|
|
393
|
+ |
|
|
394
|
+ |
</table>
|
|
395
|
+ |
</details>
|
|
396
|
+ |
|
|
397
|
+ |
<hr/>
|
368
|
398
|
|
|
369
|
|
- |
<hr/>
|
370
|
|
- |
|
371
|
|
- |
{% endfor %}
|
372
|
|
- |
|
|
399
|
+ |
{% endfor %}
|
373
|
400
|
|
{% endif %}
|
374
|
401
|
|
</div>
|
375
|
402
|
|
|