summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLibravatar Pratyush Yadav <me@yadavpratyush.com>2019-08-26 01:43:23 +0530
committerLibravatar Pratyush Yadav <me@yadavpratyush.com>2019-08-29 03:19:03 +0530
commita4fa2f0a4c1a1ef7f2987fb9d38342fcaad78a75 (patch)
tree7622f4b862d58bbd132e4789a51b77aa4b941094 /lib
parentgit-gui: return early when patch fails to apply (diff)
downloadtgif-a4fa2f0a4c1a1ef7f2987fb9d38342fcaad78a75.tar.xz
git-gui: allow undoing last revert
Accidental clicks on the revert hunk/lines buttons can cause loss of work, and can be frustrating. So, allow undoing the last revert. Right now, a stack or deque are not being used for the sake of simplicity, so only one undo is possible. Any reverts before the previous one are lost. Signed-off-by: Pratyush Yadav <me@yadavpratyush.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/diff.tcl53
1 files changed, 49 insertions, 4 deletions
diff --git a/lib/diff.tcl b/lib/diff.tcl
index 0659029632..96288fcc33 100644
--- a/lib/diff.tcl
+++ b/lib/diff.tcl
@@ -569,7 +569,7 @@ proc read_diff {fd conflict_size cont_info} {
proc apply_or_revert_hunk {x y revert} {
global current_diff_path current_diff_header current_diff_side
- global ui_diff ui_index file_states
+ global ui_diff ui_index file_states last_revert last_revert_enc
if {$current_diff_path eq {} || $current_diff_header eq {}} return
if {![lock_index apply_hunk]} return
@@ -610,18 +610,25 @@ proc apply_or_revert_hunk {x y revert} {
set e_lno end
}
+ set wholepatch "$current_diff_header[$ui_diff get $s_lno $e_lno]"
+
if {[catch {
set enc [get_path_encoding $current_diff_path]
set p [eval git_write $apply_cmd]
fconfigure $p -translation binary -encoding $enc
- puts -nonewline $p $current_diff_header
- puts -nonewline $p [$ui_diff get $s_lno $e_lno]
+ puts -nonewline $p $wholepatch
close $p} err]} {
error_popup "$failed_msg\n\n$err"
unlock_index
return
}
+ if {$revert} {
+ # Save a copy of this patch for undoing reverts.
+ set last_revert $wholepatch
+ set last_revert_enc $enc
+ }
+
$ui_diff conf -state normal
$ui_diff delete $s_lno $e_lno
$ui_diff conf -state disabled
@@ -653,7 +660,7 @@ proc apply_or_revert_hunk {x y revert} {
proc apply_or_revert_range_or_line {x y revert} {
global current_diff_path current_diff_header current_diff_side
- global ui_diff ui_index file_states
+ global ui_diff ui_index file_states last_revert
set selected [$ui_diff tag nextrange sel 0.0]
@@ -852,5 +859,43 @@ proc apply_or_revert_range_or_line {x y revert} {
return
}
+ if {$revert} {
+ # Save a copy of this patch for undoing reverts.
+ set last_revert $current_diff_header$wholepatch
+ set last_revert_enc $enc
+ }
+
+ unlock_index
+}
+
+# Undo the last line/hunk reverted. When hunks and lines are reverted, a copy
+# of the diff applied is saved. Re-apply that diff to undo the revert.
+#
+# Right now, we only use a single variable to hold the copy, and not a
+# stack/deque for simplicity, so multiple undos are not possible. Maybe this
+# can be added if the need for something like this is felt in the future.
+proc undo_last_revert {} {
+ global last_revert current_diff_path current_diff_header
+ global last_revert_enc
+
+ if {$last_revert eq {}} return
+ if {![lock_index apply_hunk]} return
+
+ set apply_cmd {apply --whitespace=nowarn}
+ set failed_msg [mc "Failed to undo last revert."]
+
+ if {[catch {
+ set enc $last_revert_enc
+ set p [eval git_write $apply_cmd]
+ fconfigure $p -translation binary -encoding $enc
+ puts -nonewline $p $last_revert
+ close $p} err]} {
+ error_popup "$failed_msg\n\n$err"
+ unlock_index
+ return
+ }
+
+ set last_revert {}
+
unlock_index
}