git-gui: Reworded 'Include' to 'Add' to match core Git.
[gitweb.git] / git-gui
diff --git a/git-gui b/git-gui
index e9d4600a252b054fefd09d7838d54fdc363526f3..1891215a646b8715ac08dfb408e9ea31a12b1d74 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
@@ -499,8 +499,8 @@ proc rescan_done {fd buf after} {
                set pathList [list]
                foreach path [array names file_states] {
                        switch -- [lindex $file_states($path) 0] {
-                       AM -
-                       MM {lappend pathList $path}
+                       A? -
+                       M? {lappend pathList $path}
                        }
                }
                if {$pathList ne {}} {
@@ -1502,10 +1502,13 @@ proc write_update_index {fd pathList totalCnt batch msg after} {
                switch -glob -- [lindex $file_states($path) 0] {
                AD -
                MD -
+               UD -
                _D {set new DD}
 
                _M -
                MM -
+               UM -
+               U_ -
                M_ {set new M_}
 
                _O -
@@ -1605,26 +1608,145 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} {
                [expr {100.0 * $update_index_cp / $totalCnt}]]
 }
 
+######################################################################
+##
+## branch management
+
+proc load_all_heads {} {
+       global all_heads tracking_branches
+
+       set all_heads [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_heads $name
+       }
+       close $fd
+
+       set all_heads [lsort $all_heads]
+}
+
+proc populate_branch_menu {m} {
+       global all_heads disable_on_lock
+
+       $m add separator
+       foreach b $all_heads {
+               $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 do_create_branch {} {
+       error "NOT IMPLEMENTED"
+}
+
+proc do_delete_branch {} {
+       error "NOT IMPLEMENTED"
+}
+
+proc switch_branch {b} {
+       global HEAD commit_type file_states current_branch
+       global selected_commit_type ui_comm
+
+       if {![lock_index switch]} return
+
+       # -- Backup the selected branch (repository_state resets it)
+       #
+       set new_branch $current_branch
+
+       # -- Our in memory state should match the repository.
+       #
+       repository_state curType curHEAD curMERGE_HEAD
+       if {[string match amend* $commit_type]
+               && $curType eq {normal}
+               && $curHEAD eq $HEAD} {
+       } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
+               info_popup {Last scanned state does not match repository state.
+
+Another Git program has modified this repository
+since the last scan.  A rescan must be performed
+before the current branch can be changed.
+
+The rescan will be automatically started now.
+}
+               unlock_index
+               rescan {set ui_status_value {Ready.}}
+               return
+       }
+
+       # -- Toss the message buffer if we are in amend mode.
+       #
+       if {[string match amend* $curType]} {
+               $ui_comm delete 0.0 end
+               $ui_comm edit reset
+               $ui_comm edit modified false
+       }
+
+       set selected_commit_type new
+       set current_branch $new_branch
+
+       unlock_index
+       error "NOT FINISHED"
+}
+
 ######################################################################
 ##
 ## 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]
                }
        }
 
@@ -2268,6 +2390,7 @@ proc do_include_all {} {
 }
 
 proc revert_helper {txt paths} {
+       global gitdir appname
        global file_states current_diff
 
        if {![lock_index begin-update]} return
@@ -2300,13 +2423,17 @@ proc revert_helper {txt paths} {
                set s "these $n files"
        }
 
+       set reponame [lindex [file split \
+               [file normalize [file dirname $gitdir]]] \
+               end]
+
        set reply [tk_dialog \
                .confirm_revert \
-               "title" \
+               "$appname ($reponame)" \
                "Revert unincluded changes in $s?
 
 Any unincluded changes will be permanently lost by the revert." \
-               questhead \
+               question \
                1 \
                {Do Nothing} \
                {Revert Changes} \
@@ -2878,6 +3005,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
@@ -2924,6 +3054,7 @@ if {!$single_commit} {
                        -font font_ui
        }
 }
+
 .mbar.repository add command -label Quit \
        -command do_quit \
        -accelerator $M1T-Q \
@@ -2963,6 +3094,24 @@ menu .mbar.edit
        -accelerator $M1T-A \
        -font font_ui
 
+# -- Branch Menu
+#
+if {!$single_commit} {
+       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
@@ -2994,13 +3143,13 @@ lappend disable_on_lock \
 lappend disable_on_lock \
        [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
-.mbar.commit add command -label {Include In Commit} \
+.mbar.commit add command -label {Add To Commit} \
        -command do_include_selection \
        -font font_ui
 lappend disable_on_lock \
        [list .mbar.commit entryconf [.mbar.commit index last] -state]
 
-.mbar.commit add command -label {Include All In Commit} \
+.mbar.commit add command -label {Add All To Commit} \
        -command do_include_all \
        -accelerator $M1T-I \
        -font font_ui
@@ -3168,7 +3317,7 @@ pack .vpane.lower.commarea.buttons.rescan -side top -fill x
 lappend disable_on_lock \
        {.vpane.lower.commarea.buttons.rescan conf -state}
 
-button .vpane.lower.commarea.buttons.incall -text {Include All} \
+button .vpane.lower.commarea.buttons.incall -text {Add All} \
        -command do_include_all \
        -font font_ui
 pack .vpane.lower.commarea.buttons.incall -side top -fill x
@@ -3524,11 +3673,9 @@ set selected_commit_type new
 wm title . "$appname ([file normalize [file dirname $gitdir]])"
 focus -force $ui_comm
 
-# -- Warn the user about environmental problems.
-#    Cygwin's Tcl does *not* pass its env array
-#    onto any processes it spawns.  This means
-#    that the git processes get none of our
-#    environment.  That may not work...
+# -- Warn the user about environmental problems.  Cygwin's Tcl
+#    does *not* pass its env array onto any processes it spawns.
+#    This means that git processes get none of our environment.
 #
 if {[is_Windows]} {
        set ignored_env 0
@@ -3581,11 +3728,17 @@ user.email settings into your personal
        unset ignored_env msg suggest_user name
 }
 
+# -- Only initialize complex UI if we are going to stay running.
+#
 if {!$single_commit} {
        load_all_remotes
+       load_all_heads
+
+       populate_branch_menu .mbar.branch
        populate_fetch_menu .mbar.fetch
        populate_pull_menu .mbar.pull
        populate_push_menu .mbar.push
 }
+
 lock_index begin-read
 after 1 do_rescan