Code

git-gui: Automatically refresh tracking branches when needed
authorShawn O. Pearce <spearce@spearce.org>
Thu, 5 Jul 2007 06:23:53 +0000 (02:23 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 9 Jul 2007 01:12:55 +0000 (21:12 -0400)
If the user is creating a new local branch and has selected to use
a tracking branch as the starting revision they probably want to
make sure they are using the absolute latest version available of
that branch.

We now offer a checkbox "Fetch Tracking Branch" (on by default)
that instructs git-gui to run git-fetch on just that one branch
before resolving the branch name into a commit SHA-1 and making
(or updating) the local branch.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
lib/branch_create.tcl
lib/console.tcl

index df3f435e11a13e6d1e812909bc0277ac6e1add2f..f708957b229962d5e6e3086fdab3e51ba4956feb 100644 (file)
@@ -12,6 +12,7 @@ field name_type  user; # type of branch name to use
 
 field opt_merge    ff; # type of merge to apply to existing branch
 field opt_checkout  1; # automatically checkout the new branch?
+field opt_fetch     1; # refetch tracking branch if used?
 field reset_ok      0; # did the user agree to reset?
 
 constructor dialog {} {
@@ -87,6 +88,11 @@ constructor dialog {} {
        pack $w.options.merge.reset -side left
        pack $w.options.merge -anchor nw
 
+       checkbutton $w.options.fetch \
+               -text {Fetch Tracking Branch} \
+               -variable @opt_fetch
+       pack $w.options.fetch -anchor nw
+
        checkbutton $w.options.checkout \
                -text {Checkout After Creation} \
                -variable @opt_checkout
@@ -107,15 +113,15 @@ constructor dialog {} {
 }
 
 method _create {} {
-       global null_sha1 repo_config
-       global all_heads current_branch
+       global repo_config current_branch
+       global M1B
 
+       set spec [$w_rev get_tracking_branch]
        switch -- $name_type {
        user {
                set newbranch $name
        }
        match {
-               set spec [$w_rev get_tracking_branch]
                if {$spec eq {}} {
                        tk_messageBox \
                                -icon error \
@@ -171,6 +177,52 @@ method _create {} {
                return
        }
 
+       if {$spec ne {} && $opt_fetch} {
+               set l_trck [lindex $spec 0]
+               set remote [lindex $spec 1]
+               set r_head [lindex $spec 2]
+               regsub ^refs/heads/ $r_head {} r_head
+
+               set c $w.fetch_trck
+               toplevel $c
+               wm title $c "Refreshing Tracking Branch"
+               wm geometry $c "+[winfo rootx $w]+[winfo rooty $w]"
+
+               set e [::console::embed \
+                       $c.console \
+                       "Fetching $r_head from $remote"]
+               pack $c.console -fill both -expand 1
+               $e exec \
+                       [list git fetch $remote +$r_head:$l_trck] \
+                       [cb _finish_fetch $newbranch $c $e]
+
+               bind $c <Visibility> [list grab $c]
+               bind $c <$M1B-Key-w> break
+               bind $c <$M1B-Key-W> break
+               wm protocol $c WM_DELETE_WINDOW [cb _noop]
+       } else {
+               _finish_create $this $newbranch
+       }
+}
+
+method _noop {} {}
+
+method _finish_fetch {newbranch c e ok} {
+       wm protocol $c WM_DELETE_WINDOW {}
+
+       if {$ok} {
+               destroy $c
+               _finish_create $this $newbranch
+       } else {
+               $e done $ok
+               button $c.close -text Close -command [list destroy $c]
+               pack $c.close -side bottom -anchor e -padx 10 -pady 10
+       }
+}
+
+method _finish_create {newbranch} {
+       global null_sha1 all_heads
+
        if {[catch {set new [$w_rev commit_or_die]}]} {
                return
        }
index ce25d92cac7b7826d8e04adc18d6e8a3c133096d..297e8defa47c19769093880a16bf5b89b0078d63 100644 (file)
@@ -7,6 +7,7 @@ field t_short
 field t_long
 field w
 field console_cr
+field is_toplevel    1; # are we our own window?
 
 constructor new {short_title long_title} {
        set t_short $short_title
@@ -15,10 +16,25 @@ constructor new {short_title long_title} {
        return $this
 }
 
+constructor embed {path title} {
+       set t_short {}
+       set t_long $title
+       set w $path
+       set is_toplevel 0
+       _init $this
+       return $this
+}
+
 method _init {} {
        global M1B
-       make_toplevel top w -autodelete 0
-       wm title $top "[appname] ([reponame]): $t_short"
+
+       if {$is_toplevel} {
+               make_toplevel top w -autodelete 0
+               wm title $top "[appname] ([reponame]): $t_short"
+       } else {
+               frame $w
+       }
+
        set console_cr 1.0
 
        frame $w.m
@@ -57,15 +73,17 @@ method _init {} {
                        $w.m.t tag remove sel 0.0 end
                "
 
-       button $w.ok -text {Close} \
-               -state disabled \
-               -command "destroy $w"
-       pack $w.ok -side bottom -anchor e -pady 10 -padx 10
+       if {$is_toplevel} {
+               button $w.ok -text {Close} \
+                       -state disabled \
+                       -command [list destroy $w]
+               pack $w.ok -side bottom -anchor e -pady 10 -padx 10
+               bind $w <Visibility> [list focus $w]
+       }
 
        bind_button3 $w.m.t "tk_popup $w.ctxm %X %Y"
        bind $w.m.t <$M1B-Key-a> "$w.m.t tag add sel 0.0 end;break"
        bind $w.m.t <$M1B-Key-A> "$w.m.t tag add sel 0.0 end;break"
-       bind $w <Visibility> "focus $w"
 }
 
 method exec {cmd {after {}}} {
@@ -159,16 +177,20 @@ method done {ok} {
        if {$ok} {
                if {[winfo exists $w.m.s]} {
                        $w.m.s conf -background green -text {Success}
-                       $w.ok conf -state normal
-                       focus $w.ok
+                       if {$is_toplevel} {
+                               $w.ok conf -state normal
+                               focus $w.ok
+                       }
                }
        } else {
                if {![winfo exists $w.m.s]} {
                        _init $this
                }
                $w.m.s conf -background red -text {Error: Command Failed}
-               $w.ok conf -state normal
-               focus $w.ok
+               if {$is_toplevel} {
+                       $w.ok conf -state normal
+                       focus $w.ok
+               }
        }
        delete_this
 }