summaryrefslogtreecommitdiff
path: root/lib/remote.tcl
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2007-05-08 03:35:48 (GMT)
committerShawn O. Pearce <spearce@spearce.org>2007-05-08 03:35:48 (GMT)
commitf522c9b5ed367172f969397589ae3d686b867ac0 (patch)
tree61315e92a1cf8f5edb67181a4e22a724195babeb /lib/remote.tcl
parentc6a5e4030320c934bca70471d04aa9e7d8e2cd67 (diff)
downloadgit-f522c9b5ed367172f969397589ae3d686b867ac0.zip
git-f522c9b5ed367172f969397589ae3d686b867ac0.tar.gz
git-f522c9b5ed367172f969397589ae3d686b867ac0.tar.bz2
git-gui: Refactor into multiple files to save my sanity
I'm finding it difficult to work with a 6,000+ line Tcl script and not go insane while looking for a particular block of code. Since most of the program is organized into different units of functionality and not all users will need all units immediately on startup we can improve things by splitting procs out into multiple files and let auto_load handle things for us. This should help not only to better organize the source, but it may also improve startup times for some users as the Tcl parser does not need to read as much script before it can show the UI. In many cases the user can avoid reading at least half of git-gui now. Unfortunately we now need a library directory in our runtime location. This is currently assumed to be $(sharedir)/git-gui/lib and its expected that the Makefile invoker will setup some sort of reasonable sharedir value for us, or let us assume its going to be $(gitexecdir)/../share. We now also require a tclsh (in TCL_PATH) to just run the Makefile, as we use tclsh to generate the tclIndex for our lib directory. I'm hoping this is not an unncessary burden on end-users who are building from source. I haven't really made any functionality changes here, this is just a huge migration of code from one file to many smaller files. All of the new changes are to setup the library path and install the library files. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'lib/remote.tcl')
-rw-r--r--lib/remote.tcl159
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/remote.tcl b/lib/remote.tcl
new file mode 100644
index 0000000..99f353e
--- /dev/null
+++ b/lib/remote.tcl
@@ -0,0 +1,159 @@
+# git-gui remote management
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc is_tracking_branch {name} {
+ global tracking_branches
+
+ if {![catch {set info $tracking_branches($name)}]} {
+ return 1
+ }
+ foreach t [array names tracking_branches] {
+ if {[string match {*/\*} $t] && [string match $t $name]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc all_tracking_branches {} {
+ global tracking_branches
+
+ set all_trackings {}
+ set cmd {}
+ foreach name [array names tracking_branches] {
+ if {[regsub {/\*$} $name {} name]} {
+ lappend cmd $name
+ } else {
+ regsub ^refs/(heads|remotes)/ $name {} name
+ lappend all_trackings $name
+ }
+ }
+
+ if {$cmd ne {}} {
+ set fd [open "| git for-each-ref --format=%(refname) $cmd" r]
+ while {[gets $fd name] > 0} {
+ regsub ^refs/(heads|remotes)/ $name {} name
+ lappend all_trackings $name
+ }
+ close $fd
+ }
+
+ return [lsort -unique $all_trackings]
+}
+
+proc load_all_remotes {} {
+ global repo_config
+ global all_remotes tracking_branches
+
+ set all_remotes [list]
+ array unset tracking_branches
+
+ set rm_dir [gitdir remotes]
+ if {[file isdirectory $rm_dir]} {
+ set all_remotes [glob \
+ -types f \
+ -tails \
+ -nocomplain \
+ -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]} 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]
+ }
+ }
+
+ set all_remotes [lsort -unique $all_remotes]
+}
+
+proc populate_fetch_menu {} {
+ global all_remotes repo_config
+
+ set m .mbar.fetch
+ foreach r $all_remotes {
+ set enable 0
+ if {![catch {set a $repo_config(remote.$r.url)}]} {
+ if {![catch {set a $repo_config(remote.$r.fetch)}]} {
+ set enable 1
+ }
+ } else {
+ catch {
+ set fd [open [gitdir remotes $r] r]
+ while {[gets $fd n] >= 0} {
+ if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
+ set enable 1
+ break
+ }
+ }
+ close $fd
+ }
+ }
+
+ if {$enable} {
+ $m add command \
+ -label "Fetch from $r..." \
+ -command [list fetch_from $r]
+ }
+ }
+}
+
+proc populate_push_menu {} {
+ global all_remotes repo_config
+
+ set m .mbar.push
+ set fast_count 0
+ foreach r $all_remotes {
+ set enable 0
+ if {![catch {set a $repo_config(remote.$r.url)}]} {
+ if {![catch {set a $repo_config(remote.$r.push)}]} {
+ set enable 1
+ }
+ } else {
+ catch {
+ set fd [open [gitdir remotes $r] r]
+ while {[gets $fd n] >= 0} {
+ if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
+ set enable 1
+ break
+ }
+ }
+ close $fd
+ }
+ }
+
+ if {$enable} {
+ if {!$fast_count} {
+ $m add separator
+ }
+ $m add command \
+ -label "Push to $r..." \
+ -command [list push_to $r]
+ incr fast_count
+ }
+ }
+}