X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=git-gui.sh;h=aa8f0ba067a0bdb041fc854be3ebf9eb0f7c0f84;hb=a4b1786b954917294483feb176e6ca473e01b615;hp=e4676bf7950ab86452a435cdf26710ea7e32b3c7;hpb=6858efbda324ab30f8857a06000933bcc55b11cc;p=git.git diff --git a/git-gui.sh b/git-gui.sh index e4676bf79..aa8f0ba06 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -543,33 +543,37 @@ proc prune_selection {} { ## diff proc clear_diff {} { - global ui_diff current_diff ui_index ui_workdir + global ui_diff current_diff_path ui_index ui_workdir $ui_diff conf -state normal $ui_diff delete 0.0 end $ui_diff conf -state disabled - set current_diff {} + set current_diff_path {} $ui_index tag remove in_diff 0.0 end $ui_workdir tag remove in_diff 0.0 end } proc reshow_diff {} { - global current_diff ui_status_value file_states - - if {$current_diff eq {} - || [catch {set s $file_states($current_diff)}]} { + global ui_status_value file_states file_lists + global current_diff_path current_diff_side + + set p $current_diff_path + if {$p eq {} + || $current_diff_side eq {} + || [catch {set s $file_states($p)}] + || [lsearch -sorted $file_lists($current_diff_side) $p] == -1} { clear_diff } else { - show_diff $current_diff + show_diff $p $current_diff_side } } proc handle_empty_diff {} { - global current_diff file_states file_lists + global current_diff_path file_states file_lists - set path $current_diff + set path $current_diff_path set s $file_states($path) if {[lindex $s 0] ne {_M}} return @@ -595,10 +599,11 @@ files list, to prevent possible confusion. display_file $path __ } -proc show_diff {path {w {}} {lno {}}} { +proc show_diff {path w {lno {}}} { global file_states file_lists global is_3way_diff diff_active repo_config - global ui_diff current_diff ui_status_value + global ui_diff ui_status_value ui_index ui_workdir + global current_diff_path current_diff_side if {$diff_active || ![lock_index read]} return @@ -620,21 +625,13 @@ proc show_diff {path {w {}} {lno {}}} { set m [lindex $s 0] set is_3way_diff 0 set diff_active 1 - set current_diff $path + set current_diff_path $path + set current_diff_side $w set ui_status_value "Loading diff of [escape_path $path]..." - set cmd [list | git diff-index] - lappend cmd --no-color - if {$repo_config(gui.diffcontext) > 0} { - lappend cmd "-U$repo_config(gui.diffcontext)" - } - lappend cmd -p - - switch $m { - MM { - lappend cmd -c - } - _O { + # - Git won't give us the diff, there's nothing to compare to! + # + if {$m eq {_O}} { if {[catch { set fd [open $path r] set content [read $fd] @@ -654,9 +651,27 @@ proc show_diff {path {w {}} {lno {}}} { set ui_status_value {Ready.} return } + + set cmd [list | git] + if {$w eq $ui_index} { + lappend cmd diff-index + lappend cmd --cached + } elseif {$w eq $ui_workdir} { + if {[string index $m 0] eq {U}} { + lappend cmd diff + } else { + lappend cmd diff-files + } } - lappend cmd [PARENT] + lappend cmd -p + lappend cmd --no-color + if {$repo_config(gui.diffcontext) > 0} { + lappend cmd "-U$repo_config(gui.diffcontext)" + } + if {$w eq $ui_index} { + lappend cmd [PARENT] + } lappend cmd -- lappend cmd $path @@ -681,6 +696,7 @@ proc read_diff {fd} { # -- Cleanup uninteresting diff header lines. # if {[string match {diff --git *} $line]} continue + if {[string match {diff --cc *} $line]} continue if {[string match {diff --combined *} $line]} continue if {[string match {--- *} $line]} continue if {[string match {+++ *} $line]} continue @@ -692,27 +708,49 @@ proc read_diff {fd} { # if {[string match {@@@ *} $line]} {set is_3way_diff 1} - # -- Reformat a 3 way diff, 'cause its too weird. - # - if {$is_3way_diff} { + if {[string match {index *} $line]} { + set tags {} + } elseif {$is_3way_diff} { set op [string range $line 0 1] switch -- $op { + { } {set tags {}} {@@} {set tags d_@} - {++} {set tags d_+ ; set op { +}} - {--} {set tags d_- ; set op { -}} - { +} {set tags d_++; set op {++}} - { -} {set tags d_--; set op {--}} - {+ } {set tags d_-+; set op {-+}} - {- } {set tags d_+-; set op {+-}} - default {set tags {}} + { +} {set tags d_s+} + { -} {set tags d_s-} + {+ } {set tags d_+s} + {- } {set tags d_-s} + {--} {set tags d_--} + {++} { + if {[regexp {^\+\+([<>]{7} |={7})} $line _g op]} { + set line [string replace $line 0 1 { }] + set tags d$op + } else { + set tags d_++ + } + } + default { + puts "error: Unhandled 3 way diff marker: {$op}" + set tags {} + } } - set line [string replace $line 0 1 $op] } else { - switch -- [string index $line 0] { - @ {set tags d_@} - + {set tags d_+} - - {set tags d_-} - default {set tags {}} + set op [string index $line 0] + switch -- $op { + { } {set tags {}} + {@} {set tags d_@} + {-} {set tags d_-} + {+} { + if {[regexp {^\+([<>]{7} |={7})} $line _g op]} { + set line [string replace $line 0 0 { }] + set tags d$op + } else { + set tags d_+ + } + } + default { + puts "error: Unhandled 2 way diff marker: {$op}" + set tags {} + } } } $ui_diff insert end $line $tags @@ -1285,12 +1323,27 @@ proc display_file {path state} { set new_m [lindex $s 0] set icon_name [lindex $s 1] - display_file_helper $ui_index $path $icon_name \ - [string index $old_m 0] \ - [string index $new_m 0] - display_file_helper $ui_workdir $path $icon_name \ - [string index $old_m 1] \ - [string index $new_m 1] + set o [string index $old_m 0] + set n [string index $new_m 0] + if {$o eq {U}} { + set o _ + } + if {$n eq {U}} { + set n _ + } + display_file_helper $ui_index $path $icon_name $o $n + + if {[string index $old_m 0] eq {U}} { + set o U + } else { + set o [string index $old_m 1] + } + if {[string index $new_m 0] eq {U}} { + set n U + } else { + set n [string index $new_m 1] + } + display_file_helper $ui_workdir $path $icon_name $o $n if {$new_m eq {__}} { unset file_states($path) @@ -1330,13 +1383,20 @@ proc display_all_files {} { set m [lindex $s 0] set icon_name [lindex $s 1] - if {[string index $m 0] ne {_}} { + set s [string index $m 0] + if {$s ne {U} && $s ne {_}} { display_all_files_helper $ui_index $path \ - $icon_name [string index $m 0] + $icon_name $s } - if {[string index $m 1] ne {_}} { + + if {[string index $m 0] eq {U}} { + set s U + } else { + set s [string index $m 1] + } + if {$s ne {_}} { display_all_files_helper $ui_workdir $path \ - $icon_name [string index $m 1] + $icon_name $s } } @@ -1379,7 +1439,7 @@ proc update_indexinfo {msg pathList after} { proc write_update_indexinfo {fd pathList totalCnt batch msg after} { global update_index_cp ui_status_value - global file_states current_diff + global file_states current_diff_path if {$update_index_cp >= $totalCnt} { close $fd @@ -1451,7 +1511,7 @@ proc update_index {msg pathList after} { proc write_update_index {fd pathList totalCnt batch msg after} { global update_index_cp ui_status_value - global file_states current_diff + global file_states current_diff_path if {$update_index_cp >= $totalCnt} { close $fd @@ -1471,7 +1531,13 @@ proc write_update_index {fd pathList totalCnt batch msg after} { ?D {set new D_} _O - AM {set new A_} - U_ - + U? { + if {[file exists $path]} { + set new M_ + } else { + set new D_ + } + } ?M {set new M_} ?? {continue} } @@ -1527,7 +1593,7 @@ proc checkout_index {msg pathList after} { proc write_checkout_index {fd pathList totalCnt batch msg after} { global update_index_cp ui_status_value - global file_states current_diff + global file_states current_diff_path if {$update_index_cp >= $totalCnt} { close $fd @@ -1674,6 +1740,9 @@ proc do_create_branch_action {w} { set all_heads [lsort $all_heads] populate_branch_menu destroy $w + if {$create_branch_checkout} { + switch_branch $newbranch + } } proc do_create_branch {} { @@ -1681,7 +1750,7 @@ proc do_create_branch {} { global create_branch_checkout create_branch_revtype global create_branch_head create_branch_trackinghead - set create_branch_checkout true + set create_branch_checkout 1 set create_branch_revtype head set create_branch_head $current_branch set create_branch_trackinghead {} @@ -1792,8 +1861,6 @@ proc do_create_branch {} { -font font_ui checkbutton $w.postActions.checkout \ -text {Checkout after creation} \ - -offvalue false \ - -onvalue true \ -variable create_branch_checkout \ -font font_ui pack $w.postActions.checkout -anchor nw @@ -1811,43 +1878,44 @@ proc do_delete_branch_action {w} { global delete_branch_checkhead delete_branch_head set to_delete [list] - set msg {Are you sure you want to delete the following branches? - -} + set not_merged [list] foreach i [$w.list.l curselection] { set b [$w.list.l get $i] if {[catch {set o [exec git rev-parse --verify $b]}]} continue if {$delete_branch_checkhead} { + if {$b eq $delete_branch_head} continue if {[catch {set m [exec git merge-base $o $delete_branch_head]}]} continue - if {$o ne $m} continue + if {$o ne $m} { + lappend not_merged $b + continue + } } lappend to_delete [list $b $o] - append msg " - $b\n" } - if {$to_delete eq {}} { + if {$not_merged ne {}} { + set msg "The following branches are not completely merged into $delete_branch_head: + + - [join $not_merged "\n - "]" tk_messageBox \ -icon info \ -type ok \ -title [wm title $w] \ -parent $w \ - -message {No branches are able to be deleted. - -This is likely because you did not select any branches, -or all selected branches are not completely merged. -} - return + -message $msg } - append msg { -It can be difficult to recover deleted branches. + if {$to_delete eq {}} return + if {!$delete_branch_checkhead} { + set msg {Recovering deleted branches is difficult. -Delete the above branches?} - if {[tk_messageBox \ - -icon warning \ - -type yesno \ - -title [wm title $w] \ - -parent $w \ - -message $msg] ne yes} { - return +Delete the selected branches?} + if {[tk_messageBox \ + -icon warning \ + -type yesno \ + -title [wm title $w] \ + -parent $w \ + -message $msg] ne yes} { + return + } } set failed {} @@ -2234,6 +2302,7 @@ set all_icons(U$ui_index) file_merge set all_icons(_$ui_workdir) file_plain set all_icons(M$ui_workdir) file_mod set all_icons(D$ui_workdir) file_question +set all_icons(U$ui_workdir) file_merge set all_icons(O$ui_workdir) file_plain set max_status_desc 0 @@ -2255,6 +2324,7 @@ foreach i { {DO "Staged for removal, still present"} {U_ "Requires merge resolution"} + {UU "Requires merge resolution"} {UM "Requires merge resolution"} {UD "Requires merge resolution"} } { @@ -2570,7 +2640,7 @@ proc do_rescan {} { } proc unstage_helper {txt paths} { - global file_states current_diff + global file_states current_diff_path if {![lock_index begin-update]} return @@ -2582,7 +2652,7 @@ proc unstage_helper {txt paths} { M? - D? { lappend pathList $path - if {$path eq $current_diff} { + if {$path eq $current_diff_path} { set after {reshow_diff;} } } @@ -2599,21 +2669,21 @@ proc unstage_helper {txt paths} { } proc do_unstage_selection {} { - global current_diff selected_paths + global current_diff_path selected_paths if {[array size selected_paths] > 0} { unstage_helper \ {Unstaging selected files from commit} \ [array names selected_paths] - } elseif {$current_diff ne {}} { + } elseif {$current_diff_path ne {}} { unstage_helper \ - "Unstaging [short_path $current_diff] from commit" \ - [list $current_diff] + "Unstaging [short_path $current_diff_path] from commit" \ + [list $current_diff_path] } } proc add_helper {txt paths} { - global file_states current_diff + global file_states current_diff_path if {![lock_index begin-update]} return @@ -2626,7 +2696,7 @@ proc add_helper {txt paths} { ?D - U? { lappend pathList $path - if {$path eq $current_diff} { + if {$path eq $current_diff_path} { set after {reshow_diff;} } } @@ -2643,16 +2713,16 @@ proc add_helper {txt paths} { } proc do_add_selection {} { - global current_diff selected_paths + global current_diff_path selected_paths if {[array size selected_paths] > 0} { add_helper \ {Adding selected files} \ [array names selected_paths] - } elseif {$current_diff ne {}} { + } elseif {$current_diff_path ne {}} { add_helper \ - "Adding [short_path $current_diff]" \ - [list $current_diff] + "Adding [short_path $current_diff_path]" \ + [list $current_diff_path] } } @@ -2671,7 +2741,7 @@ proc do_add_all {} { } proc revert_helper {txt paths} { - global file_states current_diff + global file_states current_diff_path if {![lock_index begin-update]} return @@ -2683,7 +2753,7 @@ proc revert_helper {txt paths} { ?M - ?D { lappend pathList $path - if {$path eq $current_diff} { + if {$path eq $current_diff_path} { set after {reshow_diff;} } } @@ -2722,16 +2792,16 @@ Any unadded changes will be permanently lost by the revert." \ } proc do_revert_selection {} { - global current_diff selected_paths + global current_diff_path selected_paths if {[array size selected_paths] > 0} { revert_helper \ {Reverting selected files} \ [array names selected_paths] - } elseif {$current_diff ne {}} { + } elseif {$current_diff_path ne {}} { revert_helper \ - "Reverting [short_path $current_diff]" \ - [list $current_diff] + "Reverting [short_path $current_diff_path]" \ + [list $current_diff_path] } } @@ -3113,7 +3183,7 @@ proc do_macosx_app {} { } proc toggle_or_diff {w x y} { - global file_states file_lists current_diff ui_index ui_workdir + global file_states file_lists current_diff_path ui_index ui_workdir global last_clicked selected_paths set pos [split [$w index @$x,$y] .] @@ -3131,7 +3201,7 @@ proc toggle_or_diff {w x y} { $ui_workdir tag remove in_sel 0.0 end if {$col == 0} { - if {$current_diff eq $path} { + if {$current_diff_path eq $path} { set after {reshow_diff;} } else { set after {} @@ -3737,17 +3807,17 @@ bind_button3 $ui_comm "tk_popup $ctxm %X %Y" # -- Diff Header # -set current_diff {} +set current_diff_path {} set diff_actions [list] -proc trace_current_diff {varname args} { - global current_diff diff_actions file_states - if {$current_diff eq {}} { +proc trace_current_diff_path {varname args} { + global current_diff_path diff_actions file_states + if {$current_diff_path eq {}} { set s {} set f {} set p {} set o disabled } else { - set p $current_diff + set p $current_diff_path set s [mapdesc [lindex $file_states($p) 0] $p] set f {File:} set p [escape_path $p] @@ -3761,7 +3831,7 @@ proc trace_current_diff {varname args} { uplevel #0 $w $o } } -trace add variable current_diff write trace_current_diff +trace add variable current_diff_path write trace_current_diff_path frame .vpane.lower.diff.header -background orange label .vpane.lower.diff.header.status \ @@ -3793,7 +3863,7 @@ $ctxm add command \ clipboard append \ -format STRING \ -type STRING \ - -- $current_diff + -- $current_diff_path } lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state] bind_button3 .vpane.lower.diff.header.path "tk_popup $ctxm %X %Y" @@ -3819,16 +3889,33 @@ pack .vpane.lower.diff.header -side top -fill x pack .vpane.lower.diff.body -side bottom -fill both -expand 1 $ui_diff tag conf d_@ -font font_diffbold -$ui_diff tag conf d_+ -foreground blue -$ui_diff tag conf d_- -foreground red -$ui_diff tag conf d_++ -foreground {#00a000} -$ui_diff tag conf d_-- -foreground {#a000a0} -$ui_diff tag conf d_+- \ - -foreground red \ - -background {light goldenrod yellow} -$ui_diff tag conf d_-+ \ +$ui_diff tag conf d_+ -foreground blue +$ui_diff tag conf d_- -foreground red + +$ui_diff tag conf d_++ -foreground blue +$ui_diff tag conf d_-- -foreground red +$ui_diff tag conf d_+s \ -foreground blue \ -background azure2 +$ui_diff tag conf d_-s \ + -foreground red \ + -background azure2 +$ui_diff tag conf d_s+ \ + -foreground blue \ + -background {light goldenrod yellow} +$ui_diff tag conf d_s- \ + -foreground red \ + -background {light goldenrod yellow} + +$ui_diff tag conf d<<<<<<< \ + -foreground orange \ + -font font_diffbold +$ui_diff tag conf d======= \ + -foreground orange \ + -font font_diffbold +$ui_diff tag conf d>>>>>>> \ + -foreground orange \ + -font font_diffbold # -- Diff Body Context Menu # @@ -3973,7 +4060,7 @@ set MERGE_HEAD [list] set commit_type {} set empty_tree {} set current_branch {} -set current_diff {} +set current_diff_path {} set selected_commit_type new wm title . "[appname] ([file normalize [file dirname [gitdir]]])"