field origin_url {} ; # Where we are cloning from
field origin_name origin ; # What we shall call 'origin'
field clone_type hardlink ; # Type of clone to construct
+field recursive true ; # Recursive cloning flag
field readtree_err ; # Error output from read-tree (if any)
field sorted_recent ; # recent repositories (sorted)
constructor pick {} {
global M1T M1B use_ttk NS
+ if {[set maxrecent [get_config gui.maxrecentrepo]] eq {}} {
+ set maxrecent 10
+ }
+
make_dialog top w
wm title $top [mc "Git Gui"]
-label [mc "Recent Repositories"]
}
+ if {[set lenrecent [llength $sorted_recent]] < $maxrecent} {
+ set lenrecent $maxrecent
+ }
+
${NS}::label $w_body.space
${NS}::label $w_body.recentlabel \
-anchor w \
-background [get_bg_color $w_body.recentlabel] \
-wrap none \
-width 50 \
- -height 10
+ -height $lenrecent
$w_recentlist tag conf link \
-foreground blue \
-underline 1
proc _get_recentrepos {} {
set recent [list]
- foreach p [get_config gui.recentrepo] {
+ foreach p [lsort -unique [get_config gui.recentrepo]] {
if {[_is_git [file join $p .git]]} {
lappend recent $p
} else {
_unset_recentrepo $p
}
}
- return [lsort $recent]
+ return $recent
}
proc _unset_recentrepo {p} {
regsub -all -- {([()\[\]{}\.^$+*?\\])} $p {\\\1} p
- git config --global --unset gui.recentrepo "^$p\$"
+ catch {git config --global --unset-all gui.recentrepo "^$p\$"}
load_config 1
}
set i [lsearch $recent $path]
if {$i >= 0} {
_unset_recentrepo $path
- set recent [lreplace $recent $i $i]
}
- lappend recent $path
git config --global --add gui.recentrepo $path
load_config 1
+ set recent [get_config gui.recentrepo]
+
+ if {[set maxrecent [get_config gui.maxrecentrepo]] eq {}} {
+ set maxrecent 10
+ }
- while {[llength $recent] > 10} {
+ while {[llength $recent] > $maxrecent} {
_unset_recentrepo [lindex $recent 0]
- set recent [lrange $recent 1 end]
+ set recent [get_config gui.recentrepo]
}
}
destroy $w_body
if {![winfo exists $w_next]} {
${NS}::button $w_next -default active
- pack $w_next -side right -padx 5 -before $w_quit
+ set pos -before
+ if {[tk windowingsystem] eq "win32"} { set pos -after }
+ pack $w_next -side right -padx 5 $pos $w_quit
}
_do_$action $this
}
return 1
}
-proc _is_git {path} {
+proc _is_git {path {outdir_var ""}} {
+ if {$outdir_var ne ""} {
+ upvar 1 $outdir_var outdir
+ }
+ if {[file isfile $path]} {
+ set fp [open $path r]
+ gets $fp line
+ close $fp
+ if {[regexp "^gitdir: (.+)$" $line line link_target]} {
+ set path [file join [file dirname $path] $link_target]
+ set path [file normalize $path]
+ }
+ }
+
if {[file exists [file join $path HEAD]]
&& [file exists [file join $path objects]]
&& [file exists [file join $path config]]} {
+ set outdir $path
return 1
}
if {[is_Cygwin]} {
if {[file exists [file join $path HEAD]]
&& [file exists [file join $path objects.lnk]]
&& [file exists [file join $path config.lnk]]} {
+ set outdir $path
return 1
}
}
foreach r $w_types {
pack $r -anchor w
}
+ ${NS}::checkbutton $args.type_f.recursive \
+ -text [mc "Recursively clone submodules too"] \
+ -variable @recursive \
+ -onvalue true -offvalue false
+ pack $args.type_f.recursive -anchor w
grid $args.type_l $args.type_f -sticky new
grid columnconfigure $args 1 -weight 1
fileevent $fd readable [cb _readtree_wait $fd]
}
+method _do_validate_submodule_cloning {ok} {
+ if {$ok} {
+ $o_cons done $ok
+ set done 1
+ } else {
+ _clone_failed $this [mc "Cannot clone submodules."]
+ }
+}
+
+method _do_clone_submodules {} {
+ if {$recursive eq {true}} {
+ destroy $w_body
+ set o_cons [console::embed \
+ $w_body \
+ [mc "Cloning submodules"]]
+ pack $w_body -fill both -expand 1 -padx 10
+ $o_cons exec \
+ [list git submodule update --init --recursive] \
+ [cb _do_validate_submodule_cloning]
+ } else {
+ set done 1
+ }
+}
+
method _readtree_wait {fd} {
set buf [read $fd]
$o_cons update_meter $buf
fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
fileevent $fd_ph readable [cb _postcheckout_wait $fd_ph]
} else {
- set done 1
+ _do_clone_submodules $this
}
}
hook_failed_popup post-checkout $pch_error 0
}
unset pch_error
- set done 1
+ _do_clone_submodules $this
return
}
fconfigure $fd_ph -blocking 0
}
method _do_open2 {} {
- if {![_is_git [file join $local_path .git]]} {
+ if {![_is_git [file join $local_path .git] actualgit]} {
error_popup [mc "Not a Git repository: %s" [file tail $local_path]]
return
}
}
_append_recentrepos [pwd]
- set ::_gitdir .git
+ set ::_gitdir $actualgit
set ::_prefix {}
set done 1
}