@matheusbsbs / matheus-bagliano / commits / b2ca414973
Fork 0

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 {}} {