summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 6fc835a)
raw | patch | inline | side by side (parent: 6fc835a)
author | Alexander Gavrilov <angavrilov@gmail.com> | |
Sat, 20 Sep 2008 08:19:18 +0000 (12:19 +0400) | ||
committer | Shawn O. Pearce <spearce@spearce.org> | |
Wed, 24 Sep 2008 19:51:43 +0000 (12:51 -0700) |
This restores functionality of the file icon for unmerged files.
Safety is enforced by loading the diff and checking for lines
that look like conflict markers. If such lines are found, or
the conflict involves deletion and/or symlinks, a confirmation
dialog is presented. Otherwise, the icon immediately stages the
working copy version of the file.
Includes a revert of 2fe5b2ee42897a3acc78e5ddaace3775eb2713ca
(Restore ability to Stage Working Copy for conflicts)
Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
Tested-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Safety is enforced by loading the diff and checking for lines
that look like conflict markers. If such lines are found, or
the conflict involves deletion and/or symlinks, a confirmation
dialog is presented. Otherwise, the icon immediately stages the
working copy version of the file.
Includes a revert of 2fe5b2ee42897a3acc78e5ddaace3775eb2713ca
(Restore ability to Stage Working Copy for conflicts)
Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com>
Tested-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui.sh | patch | blob | history | |
lib/diff.tcl | patch | blob | history | |
lib/mergetool.tcl | patch | blob | history |
diff --git a/git-gui.sh b/git-gui.sh
index 03c450d73f06574381b2a2dc8e765237fbcfc03e..4085e8fea59f2b819812f20185df89379d851c0b 100755 (executable)
--- a/git-gui.sh
+++ b/git-gui.sh
set is_detached 0
set current_diff_path {}
set is_3way_diff 0
+set is_conflict_diff 0
set selected_commit_type new
set nullid "0000000000000000000000000000000000000000"
$ui_index tag remove in_sel 0.0 end
$ui_workdir tag remove in_sel 0.0 end
- # Do not stage files with conflicts
+ # Determine the state of the file
if {[info exists file_states($path)]} {
set state [lindex $file_states($path) 0]
} else {
set state {__}
}
- if {[string first {U} $state] >= 0} {
- set col 1
- }
-
# Restage the file, or simply show the diff
if {$col == 0 && $y > 1} {
+ # Conflicts need special handling
+ if {[string first {U} $state] >= 0} {
+ merge_stage_workdir $path $w $lno
+ return
+ }
+
if {[string index $state 1] eq {O}} {
set mmask {}
} else {
-command {merge_resolve_one 1}
lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
$ctxmmg add separator
-$ctxmmg add command \
- -label [mc "Stage Working Copy"] \
- -command {merge_resolve_one 0}
-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} {
diff --git a/lib/diff.tcl b/lib/diff.tcl
index b61629676f69a4bcb5c6a42af72e0c82a69cea73..abe502d97104cb62bed308b0f5025c9d014834fb 100644 (file)
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
rescan ui_ready 0
}
-proc show_diff {path w {lno {}} {scroll_pos {}}} {
+proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
global file_states file_lists
- global is_3way_diff diff_active repo_config
+ global is_3way_diff is_conflict_diff diff_active repo_config
global ui_diff ui_index ui_workdir
global current_diff_path current_diff_side current_diff_header
global current_diff_queue
set s $file_states($path)
set m [lindex $s 0]
+ set is_conflict_diff 0
set current_diff_path $path
set current_diff_side $w
set current_diff_queue {}
ui_status [mc "Loading diff of %s..." [escape_path $path]]
+ set cont_info [list $scroll_pos $callback]
+
if {[string first {U} $m] >= 0} {
- merge_load_stages $path [list show_unmerged_diff $scroll_pos]
+ merge_load_stages $path [list show_unmerged_diff $cont_info]
} elseif {$m eq {_O}} {
- show_other_diff $path $w $m $scroll_pos
+ show_other_diff $path $w $m $cont_info
} else {
- start_show_diff $scroll_pos
+ start_show_diff $cont_info
}
}
-proc show_unmerged_diff {scroll_pos} {
+proc show_unmerged_diff {cont_info} {
global current_diff_path current_diff_side
- global merge_stages ui_diff
+ global merge_stages ui_diff is_conflict_diff
global current_diff_queue
if {$merge_stages(2) eq {}} {
+ set is_conflict_diff 1
lappend current_diff_queue \
[list "LOCAL: deleted\nREMOTE:\n" d======= \
[list ":1:$current_diff_path" ":3:$current_diff_path"]]
} elseif {$merge_stages(3) eq {}} {
+ set is_conflict_diff 1
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}} {
+ set is_conflict_diff 1
lappend current_diff_queue \
[list "LOCAL:\n" d======= \
[list ":1:$current_diff_path" ":2:$current_diff_path"]]
[list "REMOTE:\n" d======= \
[list ":1:$current_diff_path" ":3:$current_diff_path"]]
} else {
- start_show_diff $scroll_pos
+ start_show_diff $cont_info
return
}
- advance_diff_queue $scroll_pos
+ advance_diff_queue $cont_info
}
-proc advance_diff_queue {scroll_pos} {
+proc advance_diff_queue {cont_info} {
global current_diff_queue ui_diff
set item [lindex $current_diff_queue 0]
$ui_diff insert end [lindex $item 0] [lindex $item 1]
$ui_diff conf -state disabled
- start_show_diff $scroll_pos [lindex $item 2]
+ start_show_diff $cont_info [lindex $item 2]
}
-proc show_other_diff {path w m scroll_pos} {
+proc show_other_diff {path w m cont_info} {
global file_states file_lists
global is_3way_diff diff_active repo_config
global ui_diff ui_index ui_workdir
$ui_diff conf -state disabled
set diff_active 0
unlock_index
+ set scroll_pos [lindex $cont_info 0]
if {$scroll_pos ne {}} {
update
$ui_diff yview moveto $scroll_pos
}
ui_ready
+ set callback [lindex $cont_info 1]
+ if {$callback ne {}} {
+ eval $callback
+ }
return
}
}
-proc start_show_diff {scroll_pos {add_opts {}}} {
+proc start_show_diff {cont_info {add_opts {}}} {
global file_states file_lists
global is_3way_diff diff_active repo_config
global ui_diff ui_index ui_workdir
-blocking 0 \
-encoding [get_path_encoding $path] \
-translation lf
- fileevent $fd readable [list read_diff $fd $scroll_pos]
+ fileevent $fd readable [list read_diff $fd $cont_info]
}
-proc read_diff {fd scroll_pos} {
+proc read_diff {fd cont_info} {
global ui_diff diff_active
- global is_3way_diff current_diff_header
+ global is_3way_diff is_conflict_diff current_diff_header
global current_diff_queue
$ui_diff conf -state normal
{--} {set tags d_--}
{++} {
if {[regexp {^\+\+([<>]{7} |={7})} $line _g op]} {
+ set is_conflict_diff 1
set line [string replace $line 0 1 { }]
set tags d$op
} else {
{-} {set tags d_-}
{+} {
if {[regexp {^\+([<>]{7} |={7})} $line _g op]} {
+ set is_conflict_diff 1
set line [string replace $line 0 0 { }]
set tags d$op
} else {
close $fd
if {$current_diff_queue ne {}} {
- advance_diff_queue $scroll_pos
+ advance_diff_queue $cont_info
return
}
set diff_active 0
unlock_index
+ set scroll_pos [lindex $cont_info 0]
if {$scroll_pos ne {}} {
update
$ui_diff yview moveto $scroll_pos
if {[$ui_diff index end] eq {2.0}} {
handle_empty_diff
}
+ set callback [lindex $cont_info 1]
+ if {$callback ne {}} {
+ eval $callback
+ }
}
}
diff --git a/lib/mergetool.tcl b/lib/mergetool.tcl
index a44a7258bccc5bffea21b470eb297b02f0ad97af..6ab5701d937b9a719570907e745609b60d1d56a8 100644 (file)
--- a/lib/mergetool.tcl
+++ b/lib/mergetool.tcl
global current_diff_path
switch -- $stage {
- 0 { # Stage without confirmation, to minimize
- # disruption of the rerere workflow
- merge_add_resolution $current_diff_path
- return
- }
-
1 { set targetquestion [mc "Force resolution to the base version?"] }
2 { set targetquestion [mc "Force resolution to this branch?"] }
3 { set targetquestion [mc "Force resolution to the other branch?"] }
}
}
+proc merge_stage_workdir {path w lno} {
+ global current_diff_path diff_active
+
+ if {$diff_active} return
+
+ if {$path ne $current_diff_path} {
+ show_diff $path $w $lno {} [list do_merge_stage_workdir $path]
+ } else {
+ do_merge_stage_workdir $path
+ }
+}
+
+proc do_merge_stage_workdir {path} {
+ global current_diff_path is_conflict_diff
+
+ if {$path ne $current_diff_path} return;
+
+ if {$is_conflict_diff} {
+ if {[ask_popup [mc "File %s seems to have unresolved conflicts, still stage?" \
+ [short_path $path]]] ne {yes}} {
+ return
+ }
+ }
+
+ merge_add_resolution $path
+}
+
proc merge_add_resolution {path} {
global current_diff_path ui_workdir