git-gui: Show special diffs for complex conflict cases.
Add special handling for displaying diffs of modified/deleted, and symlink/mode conflicts. Currently the display is completely unusable for deciding how to resolve the conflict. New display modes: 1) Deleted/Modified conflict: e.g. LOCAL: deleted REMOTE: [diff :1:$path :3:$path] 2) Conflict involving symlinks: LOCAL: [diff :1:$path :2:$path] REMOTE: [diff :1:$path :3:$path] In order to be able to display multiple diffs, this patch adds a queue of commands to call. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Alexander Gavrilov committed
Aug 31, 2008 at 01:05 UTC
b2ca414973c3bcd00f2b94538bd9c755387f30a0
1 file changed
+89
-5
lib/diff.tcl
+89
-5
@@ -65,6 +65,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
65
global is_3way_diff diff_active repo_config
66
global ui_diff ui_index ui_workdir
67
global current_diff_path current_diff_side current_diff_header
68
+ global current_diff_queue
69
70
if {$diff_active || ![lock_index read]} return
71
@@ -82,13 +83,69 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
83
84
set s $file_states($path)
85
set m [lindex $s 0]
85
- set is_3way_diff 0
86
- set diff_active 1
86
set current_diff_path $path
87
set current_diff_side $w
89
- set current_diff_header {}
88
+ set current_diff_queue {}
89
ui_status [mc "Loading diff of %s..." [escape_path $path]]
90
91
+ if {[string first {U} $m] >= 0} {
92
+ merge_load_stages $path [list show_unmerged_diff $scroll_pos]
93
+ } elseif {$m eq {_O}} {
94
+ show_other_diff $path $w $m $scroll_pos
95
+ } else {
96
+ start_show_diff $scroll_pos
97
+ }
98
+}
99
+
100
+proc show_unmerged_diff {scroll_pos} {
101
+ global current_diff_path current_diff_side
102
+ global merge_stages ui_diff
103
+ global current_diff_queue
104
+
105
+ if {$merge_stages(2) eq {}} {
106
+ lappend current_diff_queue \
107
+ [list "LOCAL: deleted\nREMOTE:\n" d======= \
108
+ [list ":1:$current_diff_path" ":3:$current_diff_path"]]
109
+ } elseif {$merge_stages(3) eq {}} {
110
+ lappend current_diff_queue \
111
+ [list "REMOTE: deleted\nLOCAL:\n" d======= \
112
+ [list ":1:$current_diff_path" ":2:$current_diff_path"]]
113
+ } elseif {[lindex $merge_stages(1) 0] eq {120000}
114
+ || [lindex $merge_stages(2) 0] eq {120000}
115
+ || [lindex $merge_stages(3) 0] eq {120000}} {
116
+ lappend current_diff_queue \
117
+ [list "LOCAL:\n" d======= \
118
+ [list ":1:$current_diff_path" ":2:$current_diff_path"]]
119
+ lappend current_diff_queue \
120
+ [list "REMOTE:\n" d======= \
121
+ [list ":1:$current_diff_path" ":3:$current_diff_path"]]
122
+ } else {
123
+ start_show_diff $scroll_pos
124
+ return
125
+ }
126
+
127
+ advance_diff_queue $scroll_pos
128
+}
129
+
130
+proc advance_diff_queue {scroll_pos} {
131
+ global current_diff_queue ui_diff
132
+
133
+ set item [lindex $current_diff_queue 0]
134
+ set current_diff_queue [lrange $current_diff_queue 1 end]
135
+
136
+ $ui_diff conf -state normal
137
+ $ui_diff insert end [lindex $item 0] [lindex $item 1]
138
+ $ui_diff conf -state disabled
139
+
140
+ start_show_diff $scroll_pos [lindex $item 2]
141
+}
142
+
143
+proc show_other_diff {path w m scroll_pos} {
144
+ global file_states file_lists
145
+ global is_3way_diff diff_active repo_config
146
+ global ui_diff ui_index ui_workdir
147
+ global current_diff_path current_diff_side current_diff_header
148
+
149
# - Git won't give us the diff, there's nothing to compare to!
150
#
151
if {$m eq {_O}} {
@@ -167,6 +224,22 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
224
ui_ready
225
return
226
}
227
+}
228
+
229
+proc start_show_diff {scroll_pos {add_opts {}}} {
230
+ global file_states file_lists
231
+ global is_3way_diff diff_active repo_config
232
+ global ui_diff ui_index ui_workdir
233
+ global current_diff_path current_diff_side current_diff_header
234
+
235
+ set path $current_diff_path
236
+ set w $current_diff_side
237
+
238
+ set s $file_states($path)
239
+ set m [lindex $s 0]
240
+ set is_3way_diff 0
241
+ set diff_active 1
242
+ set current_diff_header {}
243
244
set cmd [list]
245
if {$w eq $ui_index} {
@@ -188,8 +261,12 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
261
if {$w eq $ui_index} {
262
lappend cmd [PARENT]
263
}
191
- lappend cmd --
192
- lappend cmd $path
264
+ if {$add_opts ne {}} {
265
+ eval lappend cmd $add_opts
266
+ } else {
267
+ lappend cmd --
268
+ lappend cmd $path
269
+ }
270
271
if {[catch {set fd [eval git_read --nice $cmd]} err]} {
272
set diff_active 0
@@ -209,6 +286,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
286
proc read_diff {fd scroll_pos} {
287
global ui_diff diff_active
288
global is_3way_diff current_diff_header
289
+ global current_diff_queue
290
291
$ui_diff conf -state normal
292
while {[gets $fd line] >= 0} {
@@ -293,6 +371,12 @@ proc read_diff {fd scroll_pos} {
371
372
if {[eof $fd]} {
373
close $fd
374
+
375
+ if {$current_diff_queue ne {}} {
376
+ advance_diff_queue $scroll_pos
377
+ return
378
+ }
379
+
380
set diff_active 0
381
unlock_index
382
if {$scroll_pos ne {}} {