From c6951ddb522a7d8ee0fc371cf9c37e727e676989 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 20 Aug 2007 00:53:04 -0400 Subject: git-gui: Fix window manager problems on ion3 cehteh on #git noticed that secondary windows such as console windows from push/fetch/merge or the blame browser failed on ion when we tried to open them a second time. The issue turned out to be the fact that on ion [winfo ismapped .] returns false if . is not visible right now because it has been obscured by another window in the same panel. So we need to keep track of whether or not the root window has been displayed for this application, and once it has been we cannot ever assume that ismapped is going to return true. Signed-off-by: Shawn O. Pearce diff --git a/git-gui.sh b/git-gui.sh index 29a790e..2686c1b 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -1936,6 +1936,12 @@ if {$browser ne {}} { } unset browser doc_path doc_url +set root_exists 0 +bind . { + bind . {} + set root_exists 1 +} + # -- Standard bindings # wm protocol . WM_DELETE_WINDOW do_quit diff --git a/lib/class.tcl b/lib/class.tcl index 24e8cec..dc21411 100644 --- a/lib/class.tcl +++ b/lib/class.tcl @@ -148,11 +148,12 @@ proc make_toplevel {t w args} { } } - if {[winfo ismapped .]} { + if {$::root_exists || [winfo ismapped .]} { regsub -all {::} $this {__} w set top .$w set pfx $top toplevel $top + set ::root_exists 1 } else { set top . set pfx {} -- cgit v0.10.2-6-g49f6 From 18a01a0da428c9e1034247e2b40c62e506b73580 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 20 Aug 2007 02:17:05 -0400 Subject: git-gui: Allow git-merge to use branch names in conflict markers Earlier when I rewrote the merge implementation for git-gui I broke it such that the conflict markers for the "theirs" side of the hunk was using a full SHA-1 ID in hex, rather than the name of the branch the user had merged. This was because I got paranoid and passed off the full SHA-1 to git-merge, instead of giving it the reference name the user saw in the merge dialog. I'd still like to resolve the SHA-1 upfront in git-gui and always use that value throughout the merge, but I can't do that until we have a full implementation of git-merge written in Tcl. Until then its more important that the conflict markers be useful to the end-user, so we need to pass off the ref name and not the SHA-1 ID. Signed-off-by: Shawn O. Pearce diff --git a/lib/merge.tcl b/lib/merge.tcl index 5de0d82..0e50919 100644 --- a/lib/merge.tcl +++ b/lib/merge.tcl @@ -114,7 +114,7 @@ method _start {} { lappend cmd --strategy=recursive lappend cmd [git fmt-merge-msg <[gitdir FETCH_HEAD]] lappend cmd HEAD - lappend cmd $cmit + lappend cmd $name set msg "Merging $current_branch and $stitle" ui_status "$msg..." -- cgit v0.10.2-6-g49f6 From ce015c213fbef39140b6192db28110bc666dc6c8 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 21 Aug 2007 02:22:53 -0400 Subject: git-gui: Paper bag fix "Stage Hunk For Commit" in diff context menu In a13ee29b975d3a9a012983309e842d942b2bbd44 I totally broke the "Stage Hunk For Commit" feature by making this menu item always appear in a disabled state, so it was never invokable. A "teaser feature", just sitting there taunting the poor user who has become used to having it available. The issue caused by a13ee was I added a test to look at the data in $file_states, but I didn't do that test correctly as it was always looking at a procedure local $file_states array, which is not defined, so the test was always true and we always disabled the menu entry. Instead we only want to disable the menu entry if the current file we are looking at has no file state information (git-gui is just a very confused little process) or it is an untracked file (and we cannot stage individual hunks). Signed-off-by: Shawn O. Pearce diff --git a/git-gui.sh b/git-gui.sh index 2686c1b..d5517b9 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -2416,15 +2416,16 @@ $ctxm add separator $ctxm add command -label {Options...} \ -command do_options proc popup_diff_menu {ctxm x y X Y} { - global current_diff_path + global current_diff_path file_states set ::cursorX $x set ::cursorY $y if {$::ui_index eq $::current_diff_side} { $ctxm entryconf $::ui_diff_applyhunk \ -state normal \ -label {Unstage Hunk From Commit} - } elseif {![info exists file_states($current_diff_path)] - || {_O} eq [lindex $file_states($::current_diff_path) 0]} { + } elseif {$current_diff_path eq {} + || ![info exists file_states($current_diff_path)] + || {_O} eq [lindex $file_states($current_diff_path) 0]} { $ctxm entryconf $::ui_diff_applyhunk \ -state disabled \ -label {Stage Hunk For Commit} -- cgit v0.10.2-6-g49f6 From 875b7c93686d16e083dcea8b544e4f204113d8de Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Wed, 22 Aug 2007 02:41:00 -0400 Subject: git-gui: Fix "unoptimized loading" to not cause git-gui to crash If the tclsh command was not available to us at the time we were "built" our lib/tclIndex just lists all of our library files and we source all of them at once during startup, rather than trying to lazily load only the procedures we need. This is a problem as some of our library code now depends upon the git-version proc, and that proc is not defined until after the library was fully loaded. I'm moving the library loading until after we have determined the version of git we are talking to, as this ensures that the required git-reversion procedure is defined before any library code can be loaded. Since error_popup is defined in the library we instead use tk_messageBox directly for errors found during the version detection. Signed-off-by: Shawn O. Pearce diff --git a/git-gui.sh b/git-gui.sh index d5517b9..b25b52f 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -62,54 +62,6 @@ if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} { ###################################################################### ## -## configure our library - -set oguilib {@@GITGUI_LIBDIR@@} -set oguirel {@@GITGUI_RELATIVE@@} -if {$oguirel eq {1}} { - set oguilib [file dirname [file dirname [file normalize $argv0]]] - set oguilib [file join $oguilib share git-gui lib] -} elseif {[string match @@* $oguirel]} { - set oguilib [file join [file dirname [file normalize $argv0]] lib] -} - -set idx [file join $oguilib tclIndex] -if {[catch {set fd [open $idx r]} err]} { - catch {wm withdraw .} - tk_messageBox \ - -icon error \ - -type ok \ - -title "git-gui: fatal error" \ - -message $err - exit 1 -} -if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} { - set idx [list] - while {[gets $fd n] >= 0} { - if {$n ne {} && ![string match #* $n]} { - lappend idx $n - } - } -} else { - set idx {} -} -close $fd - -if {$idx ne {}} { - set loaded [list] - foreach p $idx { - if {[lsearch -exact $loaded $p] >= 0} continue - source [file join $oguilib $p] - lappend loaded $p - } - unset loaded p -} else { - set auto_path [concat [list $oguilib] $auto_path] -} -unset -nocomplain oguirel idx fd - -###################################################################### -## ## read only globals set _appname [lindex [file split $argv0] end] @@ -532,7 +484,11 @@ if {$_git eq {}} { if {[catch {set _git_version [git --version]} err]} { catch {wm withdraw .} - error_popup "Cannot determine Git version: + tk_messageBox \ + -icon error \ + -type ok \ + -title "git-gui: fatal error" \ + -message "Cannot determine Git version: $err @@ -541,7 +497,11 @@ $err } if {![regsub {^git version } $_git_version {} _git_version]} { catch {wm withdraw .} - error_popup "Cannot parse Git version string:\n\n$_git_version" + tk_messageBox \ + -icon error \ + -type ok \ + -title "git-gui: fatal error" \ + -message "Cannot parse Git version string:\n\n$_git_version" exit 1 } @@ -619,7 +579,11 @@ proc git-version {args} { if {[git-version < 1.5]} { catch {wm withdraw .} - error_popup "[appname] requires Git 1.5.0 or later. + tk_messageBox \ + -icon error \ + -type ok \ + -title "git-gui: fatal error" \ + -message "[appname] requires Git 1.5.0 or later. You are using [git-version]: @@ -629,6 +593,54 @@ You are using [git-version]: ###################################################################### ## +## configure our library + +set oguilib {@@GITGUI_LIBDIR@@} +set oguirel {@@GITGUI_RELATIVE@@} +if {$oguirel eq {1}} { + set oguilib [file dirname [file dirname [file normalize $argv0]]] + set oguilib [file join $oguilib share git-gui lib] +} elseif {[string match @@* $oguirel]} { + set oguilib [file join [file dirname [file normalize $argv0]] lib] +} + +set idx [file join $oguilib tclIndex] +if {[catch {set fd [open $idx r]} err]} { + catch {wm withdraw .} + tk_messageBox \ + -icon error \ + -type ok \ + -title "git-gui: fatal error" \ + -message $err + exit 1 +} +if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} { + set idx [list] + while {[gets $fd n] >= 0} { + if {$n ne {} && ![string match #* $n]} { + lappend idx $n + } + } +} else { + set idx {} +} +close $fd + +if {$idx ne {}} { + set loaded [list] + foreach p $idx { + if {[lsearch -exact $loaded $p] >= 0} continue + source [file join $oguilib $p] + lappend loaded $p + } + unset loaded p +} else { + set auto_path [concat [list $oguilib] $auto_path] +} +unset -nocomplain oguirel idx fd + +###################################################################### +## ## feature option selection if {[regexp {^git-(.+)$} [appname] _junk subcommand]} { -- cgit v0.10.2-6-g49f6 From 9f4119eb7651c7898f385198409be4ca051bc7ef Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 23 Aug 2007 02:39:45 -0400 Subject: git-gui: Refactor diff pane popup support for future improvements The current popup_diff_menu procedure is somewhat messy as it has a few duplications of the same logic in each of the different legs of the routine. We can simplify these by setting a few state variables in the different legs. No functional change, just a cleanup to make it easier to implement future functional changes within this block. Signed-off-by: Shawn O. Pearce diff --git a/git-gui.sh b/git-gui.sh index b25b52f..559b62b 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -2432,20 +2432,19 @@ proc popup_diff_menu {ctxm x y X Y} { set ::cursorX $x set ::cursorY $y if {$::ui_index eq $::current_diff_side} { - $ctxm entryconf $::ui_diff_applyhunk \ - -state normal \ - -label {Unstage Hunk From Commit} - } elseif {$current_diff_path eq {} - || ![info exists file_states($current_diff_path)] - || {_O} eq [lindex $file_states($current_diff_path) 0]} { - $ctxm entryconf $::ui_diff_applyhunk \ - -state disabled \ - -label {Stage Hunk For Commit} + set s normal + set l "Unstage Hunk From Commit" } else { - $ctxm entryconf $::ui_diff_applyhunk \ - -state normal \ - -label {Stage Hunk For Commit} + if {$current_diff_path eq {} + || ![info exists file_states($current_diff_path)] + || {_O} eq [lindex $file_states($current_diff_path) 0]} { + set s disabled + } else { + set s normal + } + set l "Stage Hunk For Commit" } + $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l tk_popup $ctxm $X $Y } bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y] -- cgit v0.10.2-6-g49f6 From 9c9f5fa97fe078b59be14a6bcabb851745ddd48c Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Thu, 23 Aug 2007 02:44:13 -0400 Subject: git-gui: Do not offer to stage three-way diff hunks into the index git-apply does not accept a patch that was generated as a three-way combined diff format such as we see during merge conflicts. If we get such a diff in our diff viewer and try to send it to git-apply it just errors out and the user is left confused wondering why they cannot stage that hunk. Instead of feeding a known to be unacceptable hunk to git-apply we now just disable the stage/unstage context menu option if the hunk came from a three way diff. The user may still be confused about why they cannot work with a combined diff, but at least they are only confused as to why git-gui is not offering them the action. Signed-off-by: Shawn O. Pearce diff --git a/git-gui.sh b/git-gui.sh index 559b62b..743b7d4 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -738,6 +738,7 @@ set empty_tree {} set current_branch {} set is_detached 0 set current_diff_path {} +set is_3way_diff 0 set selected_commit_type new ###################################################################### @@ -2444,6 +2445,9 @@ proc popup_diff_menu {ctxm x y X Y} { } set l "Stage Hunk For Commit" } + if {$::is_3way_diff} { + set s disabled + } $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l tk_popup $ctxm $X $Y } -- cgit v0.10.2-6-g49f6 From c80d25dbce759a8483ffc1f085fdf4cd63cf9f05 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 24 Aug 2007 23:15:50 -0400 Subject: git-gui: Correct 'git gui blame' in a subdirectory David Kastrup pointed out that the following sequence was not working as we had intended: $ cd lib $ git gui blame console.tcl fatal: cannot stat path lib/console.tcl: No such file or directory The problem here was we disabled the chdir to the root of the working tree when we are running with a "bare allowed" feature such as blame or browser, but we still kept the prefix we found via `git rev-parse --show-prefix`. This caused us to try and look for the file "console.tcl" within the subdirectory but also include the subdirectory's own path from the root of the working tree. This is unlikely to succeed, unless the user just happened to have a "lib/lib/console.tcl" file in the repository, in which case we would produce the wrong result. In the case of a bare repository we shouldn't get back a value from `rev-parse --show-prefix`, so really $_prefix should only be set to the non-empty string if we are in a working tree and we are in a subdirectory of that working tree. If this is true we really want to always be at the top level of the working tree, as all paths are accessed as though they were relative to the top of the working tree. Converting $_prefix to a ../ sequence is a fairly simple approach to moving up the requisite levels. Signed-off-by: Shawn O. Pearce diff --git a/git-gui.sh b/git-gui.sh index 743b7d4..fa30ccc 100755 --- a/git-gui.sh +++ b/git-gui.sh @@ -703,7 +703,15 @@ if {![file isdirectory $_gitdir]} { error_popup "Git directory not found:\n\n$_gitdir" exit 1 } -if {![is_enabled bare]} { +if {$_prefix ne {}} { + regsub -all {[^/]+/} $_prefix ../ cdup + if {[catch {cd $cdup} err]} { + catch {wm withdraw .} + error_popup "Cannot move to top of working directory:\n\n$err" + exit 1 + } + unset cdup +} elseif {![is_enabled bare]} { if {[lindex [file split $_gitdir] end] ne {.git}} { catch {wm withdraw .} error_popup "Cannot use funny .git directory:\n\n$_gitdir" -- cgit v0.10.2-6-g49f6