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>
This commit is contained in:

committed by
Shawn O. Pearce

parent
8056cc4f29
commit
b2ca414973
94
lib/diff.tcl
94
lib/diff.tcl
@ -65,6 +65,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
|
|||||||
global is_3way_diff diff_active repo_config
|
global is_3way_diff diff_active repo_config
|
||||||
global ui_diff ui_index ui_workdir
|
global ui_diff ui_index ui_workdir
|
||||||
global current_diff_path current_diff_side current_diff_header
|
global current_diff_path current_diff_side current_diff_header
|
||||||
|
global current_diff_queue
|
||||||
|
|
||||||
if {$diff_active || ![lock_index read]} return
|
if {$diff_active || ![lock_index read]} return
|
||||||
|
|
||||||
@ -82,13 +83,69 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
|
|||||||
|
|
||||||
set s $file_states($path)
|
set s $file_states($path)
|
||||||
set m [lindex $s 0]
|
set m [lindex $s 0]
|
||||||
set is_3way_diff 0
|
|
||||||
set diff_active 1
|
|
||||||
set current_diff_path $path
|
set current_diff_path $path
|
||||||
set current_diff_side $w
|
set current_diff_side $w
|
||||||
set current_diff_header {}
|
set current_diff_queue {}
|
||||||
ui_status [mc "Loading diff of %s..." [escape_path $path]]
|
ui_status [mc "Loading diff of %s..." [escape_path $path]]
|
||||||
|
|
||||||
|
if {[string first {U} $m] >= 0} {
|
||||||
|
merge_load_stages $path [list show_unmerged_diff $scroll_pos]
|
||||||
|
} elseif {$m eq {_O}} {
|
||||||
|
show_other_diff $path $w $m $scroll_pos
|
||||||
|
} else {
|
||||||
|
start_show_diff $scroll_pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc show_unmerged_diff {scroll_pos} {
|
||||||
|
global current_diff_path current_diff_side
|
||||||
|
global merge_stages ui_diff
|
||||||
|
global current_diff_queue
|
||||||
|
|
||||||
|
if {$merge_stages(2) eq {}} {
|
||||||
|
lappend current_diff_queue \
|
||||||
|
[list "LOCAL: deleted\nREMOTE:\n" d======= \
|
||||||
|
[list ":1:$current_diff_path" ":3:$current_diff_path"]]
|
||||||
|
} elseif {$merge_stages(3) eq {}} {
|
||||||
|
lappend current_diff_queue \
|
||||||
|
[list "REMOTE: deleted\nLOCAL:\n" d======= \
|
||||||
|
[list ":1:$current_diff_path" ":2:$current_diff_path"]]
|
||||||
|
} elseif {[lindex $merge_stages(1) 0] eq {120000}
|
||||||
|
|| [lindex $merge_stages(2) 0] eq {120000}
|
||||||
|
|| [lindex $merge_stages(3) 0] eq {120000}} {
|
||||||
|
lappend current_diff_queue \
|
||||||
|
[list "LOCAL:\n" d======= \
|
||||||
|
[list ":1:$current_diff_path" ":2:$current_diff_path"]]
|
||||||
|
lappend current_diff_queue \
|
||||||
|
[list "REMOTE:\n" d======= \
|
||||||
|
[list ":1:$current_diff_path" ":3:$current_diff_path"]]
|
||||||
|
} else {
|
||||||
|
start_show_diff $scroll_pos
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
advance_diff_queue $scroll_pos
|
||||||
|
}
|
||||||
|
|
||||||
|
proc advance_diff_queue {scroll_pos} {
|
||||||
|
global current_diff_queue ui_diff
|
||||||
|
|
||||||
|
set item [lindex $current_diff_queue 0]
|
||||||
|
set current_diff_queue [lrange $current_diff_queue 1 end]
|
||||||
|
|
||||||
|
$ui_diff conf -state normal
|
||||||
|
$ui_diff insert end [lindex $item 0] [lindex $item 1]
|
||||||
|
$ui_diff conf -state disabled
|
||||||
|
|
||||||
|
start_show_diff $scroll_pos [lindex $item 2]
|
||||||
|
}
|
||||||
|
|
||||||
|
proc show_other_diff {path w m scroll_pos} {
|
||||||
|
global file_states file_lists
|
||||||
|
global is_3way_diff diff_active repo_config
|
||||||
|
global ui_diff ui_index ui_workdir
|
||||||
|
global current_diff_path current_diff_side current_diff_header
|
||||||
|
|
||||||
# - Git won't give us the diff, there's nothing to compare to!
|
# - Git won't give us the diff, there's nothing to compare to!
|
||||||
#
|
#
|
||||||
if {$m eq {_O}} {
|
if {$m eq {_O}} {
|
||||||
@ -167,6 +224,22 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
|
|||||||
ui_ready
|
ui_ready
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc start_show_diff {scroll_pos {add_opts {}}} {
|
||||||
|
global file_states file_lists
|
||||||
|
global is_3way_diff diff_active repo_config
|
||||||
|
global ui_diff ui_index ui_workdir
|
||||||
|
global current_diff_path current_diff_side current_diff_header
|
||||||
|
|
||||||
|
set path $current_diff_path
|
||||||
|
set w $current_diff_side
|
||||||
|
|
||||||
|
set s $file_states($path)
|
||||||
|
set m [lindex $s 0]
|
||||||
|
set is_3way_diff 0
|
||||||
|
set diff_active 1
|
||||||
|
set current_diff_header {}
|
||||||
|
|
||||||
set cmd [list]
|
set cmd [list]
|
||||||
if {$w eq $ui_index} {
|
if {$w eq $ui_index} {
|
||||||
@ -188,8 +261,12 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
|
|||||||
if {$w eq $ui_index} {
|
if {$w eq $ui_index} {
|
||||||
lappend cmd [PARENT]
|
lappend cmd [PARENT]
|
||||||
}
|
}
|
||||||
lappend cmd --
|
if {$add_opts ne {}} {
|
||||||
lappend cmd $path
|
eval lappend cmd $add_opts
|
||||||
|
} else {
|
||||||
|
lappend cmd --
|
||||||
|
lappend cmd $path
|
||||||
|
}
|
||||||
|
|
||||||
if {[catch {set fd [eval git_read --nice $cmd]} err]} {
|
if {[catch {set fd [eval git_read --nice $cmd]} err]} {
|
||||||
set diff_active 0
|
set diff_active 0
|
||||||
@ -209,6 +286,7 @@ proc show_diff {path w {lno {}} {scroll_pos {}}} {
|
|||||||
proc read_diff {fd scroll_pos} {
|
proc read_diff {fd scroll_pos} {
|
||||||
global ui_diff diff_active
|
global ui_diff diff_active
|
||||||
global is_3way_diff current_diff_header
|
global is_3way_diff current_diff_header
|
||||||
|
global current_diff_queue
|
||||||
|
|
||||||
$ui_diff conf -state normal
|
$ui_diff conf -state normal
|
||||||
while {[gets $fd line] >= 0} {
|
while {[gets $fd line] >= 0} {
|
||||||
@ -293,6 +371,12 @@ proc read_diff {fd scroll_pos} {
|
|||||||
|
|
||||||
if {[eof $fd]} {
|
if {[eof $fd]} {
|
||||||
close $fd
|
close $fd
|
||||||
|
|
||||||
|
if {$current_diff_queue ne {}} {
|
||||||
|
advance_diff_queue $scroll_pos
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
set diff_active 0
|
set diff_active 0
|
||||||
unlock_index
|
unlock_index
|
||||||
if {$scroll_pos ne {}} {
|
if {$scroll_pos ne {}} {
|
||||||
|
Reference in New Issue
Block a user