git-gui: Automatically skip tracking branches in branch menu.
[gitweb.git] / git-gui
diff --git a/git-gui b/git-gui
index e9d4600a252b054fefd09d7838d54fdc363526f3..7406238c9029b2cd4639361c34c50d2e910c64d0 100755 (executable)
--- a/git-gui
+++ b/git-gui
@@ -266,7 +266,7 @@ proc repository_state {ctvar hdvar mhvar} {
        if {[catch {set current_branch [exec git symbolic-ref HEAD]}]} {
                set current_branch {}
        } else {
-               regsub ^refs/(heads|tags)/ \
+               regsub ^refs/((heads|tags|remotes)/)? \
                        $current_branch \
                        {} \
                        current_branch
@@ -1605,26 +1605,96 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} {
                [expr {100.0 * $update_index_cp / $totalCnt}]]
 }
 
+######################################################################
+##
+## branch management
+
+proc load_all_branches {} {
+       global all_branches tracking_branches
+
+       set all_branches [list]
+       set cmd [list git for-each-ref]
+       lappend cmd --format=%(refname)
+       lappend cmd refs/heads
+       set fd [open "| $cmd" r]
+       while {[gets $fd line] > 0} {
+               if {![catch {set info $tracking_branches($line)}]} continue
+               if {![regsub ^refs/heads/ $line {} name]} continue
+               lappend all_branches $name
+       }
+       close $fd
+
+       set all_branches [lsort $all_branches]
+}
+
+proc populate_branch_menu {m} {
+       global all_branches disable_on_lock
+
+       $m add separator
+       foreach b $all_branches {
+               $m add radiobutton \
+                       -label $b \
+                       -command [list switch_branch $b] \
+                       -variable current_branch \
+                       -value $b \
+                       -font font_ui
+               lappend disable_on_lock \
+                       [list $m entryconf [$m index last] -state]
+       }
+}
+
+proc switch_branch {b} {
+       error "NOT IMPLEMENTED"
+}
+
 ######################################################################
 ##
 ## remote management
 
 proc load_all_remotes {} {
-       global gitdir all_remotes repo_config
+       global gitdir repo_config
+       global all_remotes tracking_branches
 
        set all_remotes [list]
+       array unset tracking_branches
+
        set rm_dir [file join $gitdir remotes]
        if {[file isdirectory $rm_dir]} {
-               set all_remotes [concat $all_remotes [glob \
+               set all_remotes [glob \
                        -types f \
                        -tails \
                        -nocomplain \
-                       -directory $rm_dir *]]
+                       -directory $rm_dir *]
+
+               foreach name $all_remotes {
+                       catch {
+                               set fd [open [file join $rm_dir $name] r]
+                               while {[gets $fd line] >= 0} {
+                                       if {![regexp {^Pull:[   ]*([^:]+):(.+)$} \
+                                               $line line src dst]} continue
+                                       if {![regexp ^refs/ $dst]} {
+                                               set dst "refs/heads/$dst"
+                                       }
+                                       set tracking_branches($dst) [list $name $src]
+                               }
+                               close $fd
+                       }
+               }
        }
 
        foreach line [array names repo_config remote.*.url] {
-               if {[regexp ^remote\.(.*)\.url\$ $line line name]} {
-                       lappend all_remotes $name
+               if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
+               lappend all_remotes $name
+
+               if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
+                       set fl {}
+               }
+               foreach line $fl {
+                       if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
+                       if {![regexp ^refs/ $dst]} {
+                               set dst "refs/heads/$dst"
+                       }
+                       set tracking_branches($dst) [list $name $src]
                }
        }
 
@@ -2878,6 +2948,9 @@ apply_config
 menu .mbar -tearoff 0
 .mbar add cascade -label Repository -menu .mbar.repository
 .mbar add cascade -label Edit -menu .mbar.edit
+if {!$single_commit} {
+       .mbar add cascade -label Branch -menu .mbar.branch
+}
 .mbar add cascade -label Commit -menu .mbar.commit
 if {!$single_commit} {
        .mbar add cascade -label Fetch -menu .mbar.fetch
@@ -2963,6 +3036,24 @@ menu .mbar.edit
        -accelerator $M1T-A \
        -font font_ui
 
+if {!$single_commit} {
+       # -- Branch Menu
+       #
+       menu .mbar.branch
+
+       .mbar.branch add command -label {Create...} \
+               -command do_create_branch \
+               -font font_ui
+       lappend disable_on_lock [list .mbar.branch entryconf \
+               [.mbar.branch index last] -state]
+
+       .mbar.branch add command -label {Delete...} \
+               -command do_delete_branch \
+               -font font_ui
+       lappend disable_on_lock [list .mbar.branch entryconf \
+               [.mbar.branch index last] -state]
+}
+
 # -- Commit Menu
 #
 menu .mbar.commit
@@ -3583,6 +3674,8 @@ user.email settings into your personal
 
 if {!$single_commit} {
        load_all_remotes
+       load_all_branches
+       populate_branch_menu .mbar.branch
        populate_fetch_menu .mbar.fetch
        populate_pull_menu .mbar.pull
        populate_push_menu .mbar.push