git-gui: Fix handling of relative paths in blame.
[gitweb.git] / git-gui.sh
index 6ed6230d3c1431df4d91973e6cc3bd846f2f9b7e..65dacf9b16c5112211dd987befce31a86c409129 100755 (executable)
@@ -940,19 +940,25 @@ git-version proc _parse_config {arr_name args} {
 }
 
 proc load_config {include_global} {
-       global repo_config global_config default_config
+       global repo_config global_config system_config default_config
 
        if {$include_global} {
+               _parse_config system_config --system
                _parse_config global_config --global
        }
        _parse_config repo_config
 
        foreach name [array names default_config] {
+               if {[catch {set v $system_config($name)}]} {
+                       set system_config($name) $default_config($name)
+               }
+       }
+       foreach name [array names system_config] {
                if {[catch {set v $global_config($name)}]} {
-                       set global_config($name) $default_config($name)
+                       set global_config($name) $system_config($name)
                }
                if {[catch {set v $repo_config($name)}]} {
-                       set repo_config($name) $default_config($name)
+                       set repo_config($name) $system_config($name)
                }
        }
 }
@@ -1485,10 +1491,8 @@ proc rescan_done {fd buf after} {
        prune_selection
        unlock_index
        display_all_files
-       if {$current_diff_path ne {}} reshow_diff
-       if {$current_diff_path eq {}} select_first_diff
-
-       uplevel #0 $after
+       if {$current_diff_path ne {}} { reshow_diff $after }
+       if {$current_diff_path eq {}} { select_first_diff $after }
 }
 
 proc prune_selection {} {
@@ -2000,16 +2004,16 @@ proc do_rescan {} {
 }
 
 proc ui_do_rescan {} {
-       rescan {force_first_diff; ui_ready}
+       rescan {force_first_diff ui_ready}
 }
 
 proc do_commit {} {
        commit_tree
 }
 
-proc next_diff {} {
+proc next_diff {{after {}}} {
        global next_diff_p next_diff_w next_diff_i
-       show_diff $next_diff_p $next_diff_w {}
+       show_diff $next_diff_p $next_diff_w {} {} $after
 }
 
 proc find_anchor_pos {lst name} {
@@ -2094,25 +2098,42 @@ proc next_diff_after_action {w path {lno {}} {mmask {}}} {
        }
 }
 
-proc select_first_diff {} {
+proc select_first_diff {after} {
        global ui_workdir
 
        if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
            [find_next_diff $ui_workdir {} 1 {[^O]$}]} {
-               next_diff
+               next_diff $after
+       } else {
+               uplevel #0 $after
        }
 }
 
-proc force_first_diff {} {
-       global current_diff_path
+proc force_first_diff {after} {
+       global ui_workdir current_diff_path file_states
 
        if {[info exists file_states($current_diff_path)]} {
                set state [lindex $file_states($current_diff_path) 0]
+       } else {
+               set state {OO}
+       }
 
-               if {[string index $state 1] ne {O}} return
+       set reselect 0
+       if {[string first {U} $state] >= 0} {
+               # Already a conflict, do nothing
+       } elseif {[find_next_diff $ui_workdir $current_diff_path {} {^_?U}]} {
+               set reselect 1
+       } elseif {[string index $state 1] ne {O}} {
+               # Already a diff & no conflicts, do nothing
+       } elseif {[find_next_diff $ui_workdir $current_diff_path {} {[^O]$}]} {
+               set reselect 1
        }
 
-       select_first_diff
+       if {$reselect} {
+               next_diff $after
+       } else {
+               uplevel #0 $after
+       }
 }
 
 proc toggle_or_diff {w x y} {
@@ -2268,6 +2289,9 @@ if {[is_enabled transport]} {
        .mbar add cascade -label [mc Merge] -menu .mbar.merge
        .mbar add cascade -label [mc Remote] -menu .mbar.remote
 }
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+       .mbar add cascade -label [mc Tools] -menu .mbar.tools
+}
 . configure -menu .mbar
 
 # -- Repository Menu
@@ -2542,6 +2566,20 @@ if {[is_MacOSX]} {
                -command do_options
 }
 
+# -- Tools Menu
+#
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+       set tools_menubar .mbar.tools
+       menu $tools_menubar
+       $tools_menubar add separator
+       $tools_menubar add command -label [mc "Add..."] -command tools_add::dialog
+       $tools_menubar add command -label [mc "Remove..."] -command tools_remove::dialog
+       set tools_tailcnt 3
+       if {[array names repo_config guitool.*.cmd] ne {}} {
+               tools_populate_all
+       }
+}
+
 # -- Help Menu
 #
 .mbar add cascade -label [mc Help] -menu .mbar.help
@@ -2592,6 +2630,20 @@ proc usage {} {
        exit 1
 }
 
+proc normalize_relpath {path} {
+       set elements {}
+       foreach item [file split $path] {
+               if {$item eq {.}} continue
+               if {$item eq {..} && [llength $elements] > 0
+                   && [lindex $elements end] ne {..}} {
+                       set elements [lrange $elements 0 end-1]
+                       continue
+               }
+               lappend elements $item
+       }
+       return [eval file join $elements]
+}
+
 # -- Not a normal commit type invocation?  Do that instead!
 #
 switch -- $subcommand {
@@ -2610,7 +2662,7 @@ blame {
        foreach a $argv {
                if {$is_path || [file exists $_prefix$a]} {
                        if {$path ne {}} usage
-                       set path $_prefix$a
+                       set path [normalize_relpath $_prefix$a]
                        break
                } elseif {$a eq {--}} {
                        if {$path ne {}} {
@@ -2633,7 +2685,7 @@ blame {
        unset is_path
 
        if {$head ne {} && $path eq {}} {
-               set path $_prefix$head
+               set path [normalize_relpath $_prefix$head]
                set head {}
        }