mirror of
https://github.com/git/git.git
synced 2024-11-25 10:54:00 +08:00
git-gui: Support resolving conflicts via the diff context menu.
If the file has merge conflicts, show a special version of the diff context menu, which includes conflict resolution commands instead of Stage Hunk/Line. This patch only supports resolving by discarding all sides except one. Discarding is the only way to resolve conflicts involving symlinks and/or deletion, excluding manual editing. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
700e560341
commit
042c232535
150
git-gui.sh
150
git-gui.sh
@ -2713,6 +2713,51 @@ $ui_diff tag raise sel
|
||||
|
||||
# -- Diff Body Context Menu
|
||||
#
|
||||
|
||||
proc create_common_diff_popup {ctxm} {
|
||||
$ctxm add command \
|
||||
-label [mc "Show Less Context"] \
|
||||
-command show_less_context
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Show More Context"] \
|
||||
-command show_more_context
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command \
|
||||
-label [mc Refresh] \
|
||||
-command reshow_diff
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc Copy] \
|
||||
-command {tk_textCopy $ui_diff}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Select All"] \
|
||||
-command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Copy All"] \
|
||||
-command {
|
||||
$ui_diff tag add sel 0.0 end
|
||||
tk_textCopy $ui_diff
|
||||
$ui_diff tag remove sel 0.0 end
|
||||
}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command \
|
||||
-label [mc "Decrease Font Size"] \
|
||||
-command {incr_font_size font_diff -1}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Increase Font Size"] \
|
||||
-command {incr_font_size font_diff 1}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command -label [mc "Options..."] \
|
||||
-command do_options
|
||||
}
|
||||
|
||||
set ctxm .vpane.lower.diff.body.ctxm
|
||||
menu $ctxm -tearoff 0
|
||||
$ctxm add command \
|
||||
@ -2726,73 +2771,60 @@ $ctxm add command \
|
||||
set ui_diff_applyline [$ctxm index last]
|
||||
lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command \
|
||||
-label [mc "Show Less Context"] \
|
||||
-command show_less_context
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Show More Context"] \
|
||||
-command show_more_context
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command \
|
||||
-label [mc Refresh] \
|
||||
-command reshow_diff
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc Copy] \
|
||||
-command {tk_textCopy $ui_diff}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Select All"] \
|
||||
-command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Copy All"] \
|
||||
-command {
|
||||
$ui_diff tag add sel 0.0 end
|
||||
tk_textCopy $ui_diff
|
||||
$ui_diff tag remove sel 0.0 end
|
||||
}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command \
|
||||
-label [mc "Decrease Font Size"] \
|
||||
-command {incr_font_size font_diff -1}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add command \
|
||||
-label [mc "Increase Font Size"] \
|
||||
-command {incr_font_size font_diff 1}
|
||||
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
|
||||
$ctxm add separator
|
||||
$ctxm add command -label [mc "Options..."] \
|
||||
-command do_options
|
||||
proc popup_diff_menu {ctxm x y X Y} {
|
||||
create_common_diff_popup $ctxm
|
||||
|
||||
set ctxmmg .vpane.lower.diff.body.ctxmmg
|
||||
menu $ctxmmg -tearoff 0
|
||||
$ctxmmg add command \
|
||||
-label [mc "Use Remote Version"] \
|
||||
-command {merge_resolve_one 3}
|
||||
lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
|
||||
$ctxmmg add command \
|
||||
-label [mc "Use Local Version"] \
|
||||
-command {merge_resolve_one 2}
|
||||
lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
|
||||
$ctxmmg add command \
|
||||
-label [mc "Revert To Base"] \
|
||||
-command {merge_resolve_one 1}
|
||||
lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
|
||||
$ctxmmg add separator
|
||||
create_common_diff_popup $ctxmmg
|
||||
|
||||
proc popup_diff_menu {ctxm ctxmmg x y X Y} {
|
||||
global current_diff_path file_states
|
||||
set ::cursorX $x
|
||||
set ::cursorY $y
|
||||
if {$::ui_index eq $::current_diff_side} {
|
||||
set l [mc "Unstage Hunk From Commit"]
|
||||
set t [mc "Unstage Line From Commit"]
|
||||
if {[info exists file_states($current_diff_path)]} {
|
||||
set state [lindex $file_states($current_diff_path) 0]
|
||||
} else {
|
||||
set l [mc "Stage Hunk For Commit"]
|
||||
set t [mc "Stage Line For Commit"]
|
||||
set state {__}
|
||||
}
|
||||
if {$::is_3way_diff
|
||||
|| $current_diff_path eq {}
|
||||
|| ![info exists file_states($current_diff_path)]
|
||||
|| {_O} eq [lindex $file_states($current_diff_path) 0]
|
||||
|| {_T} eq [lindex $file_states($current_diff_path) 0]
|
||||
|| {T_} eq [lindex $file_states($current_diff_path) 0]} {
|
||||
set s disabled
|
||||
if {[string index $state 0] eq {U}} {
|
||||
tk_popup $ctxmmg $X $Y
|
||||
} else {
|
||||
set s normal
|
||||
if {$::ui_index eq $::current_diff_side} {
|
||||
set l [mc "Unstage Hunk From Commit"]
|
||||
set t [mc "Unstage Line From Commit"]
|
||||
} else {
|
||||
set l [mc "Stage Hunk For Commit"]
|
||||
set t [mc "Stage Line For Commit"]
|
||||
}
|
||||
if {$::is_3way_diff
|
||||
|| $current_diff_path eq {}
|
||||
|| {__} eq $state
|
||||
|| {_O} eq $state
|
||||
|| {_T} eq $state
|
||||
|| {T_} eq $state} {
|
||||
set s disabled
|
||||
} else {
|
||||
set s normal
|
||||
}
|
||||
$ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
|
||||
$ctxm entryconf $::ui_diff_applyline -state $s -label $t
|
||||
tk_popup $ctxm $X $Y
|
||||
}
|
||||
$ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
|
||||
$ctxm entryconf $::ui_diff_applyline -state $s -label $t
|
||||
tk_popup $ctxm $X $Y
|
||||
}
|
||||
bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]
|
||||
bind_button3 $ui_diff [list popup_diff_menu $ctxm $ctxmmg %x %y %X %Y]
|
||||
|
||||
# -- Status Bar
|
||||
#
|
||||
|
98
lib/mergetool.tcl
Normal file
98
lib/mergetool.tcl
Normal file
@ -0,0 +1,98 @@
|
||||
# git-gui merge conflict resolution
|
||||
# parts based on git-mergetool (c) 2006 Theodore Y. Ts'o
|
||||
|
||||
proc merge_resolve_one {stage} {
|
||||
global current_diff_path
|
||||
|
||||
switch -- $stage {
|
||||
1 { set target [mc "the base version"] }
|
||||
2 { set target [mc "this branch"] }
|
||||
3 { set target [mc "the other branch"] }
|
||||
}
|
||||
|
||||
set op_question [mc "Force resolution to %s?
|
||||
Note that the diff shows only conflicting changes.
|
||||
|
||||
%s will be overwritten.
|
||||
|
||||
This operation can be undone only by restarting the merge." \
|
||||
$target [short_path $current_diff_path]]
|
||||
|
||||
if {[ask_popup $op_question] eq {yes}} {
|
||||
merge_load_stages $current_diff_path [list merge_force_stage $stage]
|
||||
}
|
||||
}
|
||||
|
||||
proc merge_add_resolution {path} {
|
||||
global current_diff_path
|
||||
|
||||
if {$path eq $current_diff_path} {
|
||||
set after {reshow_diff;}
|
||||
} else {
|
||||
set after {}
|
||||
}
|
||||
|
||||
update_index \
|
||||
[mc "Adding resolution for %s" [short_path $path]] \
|
||||
[list $path] \
|
||||
[concat $after [list ui_ready]]
|
||||
}
|
||||
|
||||
proc merge_force_stage {stage} {
|
||||
global current_diff_path merge_stages
|
||||
|
||||
if {$merge_stages($stage) ne {}} {
|
||||
git checkout-index -f --stage=$stage -- $current_diff_path
|
||||
} else {
|
||||
file delete -- $current_diff_path
|
||||
}
|
||||
|
||||
merge_add_resolution $current_diff_path
|
||||
}
|
||||
|
||||
proc merge_load_stages {path cont} {
|
||||
global merge_stages_fd merge_stages merge_stages_buf
|
||||
|
||||
if {[info exists merge_stages_fd]} {
|
||||
catch { kill_file_process $merge_stages_fd }
|
||||
catch { close $merge_stages_fd }
|
||||
}
|
||||
|
||||
set merge_stages(0) {}
|
||||
set merge_stages(1) {}
|
||||
set merge_stages(2) {}
|
||||
set merge_stages(3) {}
|
||||
set merge_stages_buf {}
|
||||
|
||||
set merge_stages_fd [eval git_read ls-files -u -z -- $path]
|
||||
|
||||
fconfigure $merge_stages_fd -blocking 0 -translation binary -encoding binary
|
||||
fileevent $merge_stages_fd readable [list read_merge_stages $merge_stages_fd $cont]
|
||||
}
|
||||
|
||||
proc read_merge_stages {fd cont} {
|
||||
global merge_stages_buf merge_stages_fd merge_stages
|
||||
|
||||
append merge_stages_buf [read $fd]
|
||||
set pck [split $merge_stages_buf "\0"]
|
||||
set merge_stages_buf [lindex $pck end]
|
||||
|
||||
if {[eof $fd] && $merge_stages_buf ne {}} {
|
||||
lappend pck {}
|
||||
set merge_stages_buf {}
|
||||
}
|
||||
|
||||
foreach p [lrange $pck 0 end-1] {
|
||||
set fcols [split $p "\t"]
|
||||
set cols [split [lindex $fcols 0] " "]
|
||||
set stage [lindex $cols 2]
|
||||
|
||||
set merge_stages($stage) [lrange $cols 0 1]
|
||||
}
|
||||
|
||||
if {[eof $fd]} {
|
||||
close $fd
|
||||
unset merge_stages_fd
|
||||
eval $cont
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user