Re: [PATCH] git-gui: offer a list of recent repositories on startup
Shawn, I attached two patches. They should eventually be both squashed into one. You can also cherry pick them from work/setup-preview in 4msysgit. I'm not yet fully convinced of the performance of the second patch. It is far from optimal, although it might be sufficient.
If you're satisfied with the current implementation you can squash them into a single commit; or ask me to do that.
More comments below, after the summary.
commit a483fdd562d6c44d68a998224e0bbb17933b624a
Author: Steffen Prohaska <prohaska@zib.de>
Date: Mon Oct 8 08:25:47 2007 +0200
git-gui: offer a list of recent repositories on startup
If git-gui is started outside a work tree the repository
chooser will offer a list of recently opend repositories.
Clicking on an entry directly opens the repository. The list of recently opened repositories is stored in the
config as gui.recentrepos. If the list grows beyond 10
entries it will be truncated. Note, only repositories that are opened through the
repository chooser will get added to the recent list.
Repositories opened from the shell will not yet be added. Signed-off-by: Steffen Prohaska <prohaska@zib.de>
commit a9f083e83717eef91ba8842ece4a3ec0824126af
Author: Steffen Prohaska <prohaska@zib.de>
Date: Mon Oct 8 08:14:34 2007 +0200
git-gui: handle list of recent repos as multi config gui.recentrepo
Instead of encoding the list of recently opened repositories
in a single config line, this commit uses multiple lines of
gui.recentrepo. An advantage is that the solution makes the list explicit
on the git config level. This may be easier to understand
if the user wants to look at the configuration. A disadvantage (of the current implementation) is that it
requires more git config calls to manage the list. This could
be optimized. But maybe not required because the list is only
updated on opening a new repository, which is already a quite
expensive operation. Signed-off-by: Steffen Prohaska <prohaska@zib.de>
On Oct 8, 2007, at 1:30 AM, Shawn O. Pearce wrote:
Show 8 quoted lines
> Steffen Prohaska <prohaska@zib.de> wrote:
>
>> + label $w_body.space
>> + label $w_body.recentlabel \
>> + -anchor w \
>> + -text "Select Recent Repository:"
>
> This string needs to be i18n'd with [mc ...].
Show 6 quoted lines
>> + listbox $w_body.recentlist \
>
> Please make a field in this class called say "w_recentlist"
> so you can use that field name instead of $w_body.recentlist.
> This simplifies the code if we ever have to change the actual path
> that the widget resides at, such as to alter the layout.
Show 17 quoted lines
>> +proc _append_recentrepos {path} {
>> + set recent [get_config gui.recentrepos]
>> + if {[lsearch $recent $path] < 0} {
>> + lappend recent $path
>> + }
>> + if {[llength $recent] > 10} {
>> + set recent [lrange $recent 1 end]
>> + }
>> + regsub -all "\[{}\]" $recent {"} recent
>> + git config --global gui.recentrepos $recent
>> +}
>
> Why treat this as a Tcl list in a single value? Why not make it
> a true multi-value configuration entry in ~/.gitconfig, like how
> remote.$name.fetch is a multi-value entry? Does Windows allow
> you to put " in a path name? Because the above regex will make
> a list of paths that contains " in one of the entries invalid.I don't think " is allowed. I wasn't able to create a file containing " in its path. Neither from the explorer nor on the command line.
Show 6 quoted lines
> I think you also want to have this function return back immediately
> if [lsearch $recent $path] >= 0 as then you don't invoke git-config
> to perform a no-op change in the configuration file. As you well
> know forking on Windows is a major cost. We shouldn't run git-config
> just because the user opened a recent repository.
>
The second patch actually runs git config several times to first remote all multi-value entries and then create them one by one. This is worse performance than before.
This could be avoided by selectively removing only a single entry. 'git config' could be asked to only remove the entry that was removed from the tcl list. But 'git config' only accepts regular expression to do so.
I don't know how to escape a simple string to a corresponding regular expression that matches only the string but nothing else.
For my problem it would be much easier if 'git config' accepted just a plain string that must be matched exactly and not a regular expression.
I see two solutions:
1) Someone explains me how to convert a string to a regular expression
matching only the input string.
2) "git config" is modified to accept a simple string as its second
argument.
Maybe we can use implementation in the second patch for now and wait
until "git config" is modified. Note, I'll not start to work on this
right
away because I want to stay focused on the basic functionality on
Windows and,
for now, do not care about performance too much.
Steffen
From a483fdd562d6c44d68a998224e0bbb17933b624a Mon Sep 17 00:00:00 2001
From: Steffen Prohaska <prohaska@zib.de>
Date: Mon, 8 Oct 2007 08:25:47 +0200
Subject: [PATCH] git-gui: offer a list of recent repositories on startup
If git-gui is started outside a work tree the repository chooser will offer a list of recently opend repositories. Clicking on an entry directly opens the repository.
The list of recently opened repositories is stored in the config as gui.recentrepos. If the list grows beyond 10 entries it will be truncated.
Note, only repositories that are opened through the repository chooser will get added to the recent list. Repositories opened from the shell will not yet be added.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
git-gui/lib/choose_repository.tcl | 49 +++++++++++++++++++++++++++++++++++++
1 files changed, 49 insertions(+), 0 deletions(-)
Show changes to git-gui/lib/choose_repository.tcl +49 −0
diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl
index 16bf67c..4f57572 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -41,6 +41,7 @@ field w_body ; # Widget holding the center content
field w_next ; # Next button
field o_cons ; # Console object (if active)
field w_types ; # List of type buttons in clone
+field w_recentlist ; # Listbox containing recent repositories
field action new ; # What action are we going to perform?
field done 0 ; # Finished picking the repository?
@@ -116,9 +117,27 @@ constructor pick {} {
-text [mc "Open Existing Repository"] \
-variable @action \
-value open
+ label $w_body.space
+ label $w_body.recentlabel \
+ -anchor w \
+ -text [mc "Select Recent Repository:"]
+ set w_recentlist $w_body.recentlist
+ listbox $w_recentlist \
+ -relief flat \
+ -width 50 \
+ -height 10 \
+ -exportselection false \
+ -selectmode select
+ foreach p [_get_recentrepos] {
+ $w_recentlist insert end $p
+ }
+ bind $w_recentlist <<ListboxSelect>> [cb _open_recent]
pack $w_body.new -anchor w -fill x
pack $w_body.clone -anchor w -fill x
pack $w_body.open -anchor w -fill x
+ pack $w_body.space -anchor w -fill x
+ pack $w_body.recentlabel -anchor w -fill x
+ pack $w_recentlist -anchor w -fill x
pack $w_body -fill x -padx 10 -pady 10
frame $w.buttons
@@ -171,6 +190,34 @@ method _invoke_next {} {
}
}
+proc _get_recentrepos {} {
+ set recent [list]
+ foreach p [get_config gui.recentrepos] {
+ if {[file isdirectory [file join $p .git]]} {
+ lappend recent $p
+ }
+ }
+ return [lsort $recent]
+}
+
+proc _append_recentrepos {path} {
+ set recent [get_config gui.recentrepos]
+ if {[lsearch $recent $path] < 0} {
+ lappend recent $path
+ }
+ if {[llength $recent] > 10} {
+ set recent [lrange $recent 1 end]
+ }
+ regsub -all "\[{}\]" $recent {"} recent
+ git config --global gui.recentrepos $recent
+}
+
+method _open_recent {} {
+ set id [$w_recentlist curselection]
+ set local_path [$w_recentlist get $id]
+ _do_open2 $this
+}
+
method _next {} {
destroy $w_body
_do_$action $this
@@ -893,6 +940,8 @@ method _do_open2 {} {
return
}
+ _append_recentrepos $local_path
+
set ::_gitdir .git
set ::_prefix {}
set done 1
--
1.5.3.mingw.1.99.gdbfb3
From a9f083e83717eef91ba8842ece4a3ec0824126af Mon Sep 17 00:00:00 2001
From: Steffen Prohaska <prohaska@zib.de>
Date: Mon, 8 Oct 2007 08:14:34 +0200
Subject: [PATCH] git-gui: handle list of recent repos as multi config gui.recentrepo
Instead of encoding the list of recently opened repositories
in a single config line, this commit uses multiple lines of
gui.recentrepo.
An advantage is that the solution makes the list explicit
on the git config level. This may be easier to understand
if the user wants to look at the configuration.
A disadvantage (of the current implementation) is that it
requires more git config calls to manage the list. This could
be optimized. But maybe not required because the list is only
updated on opening a new repository, which is already a quite
expensive operation.
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
---
git-gui/git-gui.sh | 3 ++-
git-gui/lib/choose_repository.tcl | 15 +++++++++------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 3f5927f..8e56294 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -206,7 +206,8 @@ proc disable_option {option} {
proc is_many_config {name} {
switch -glob -- $name {
remote.*.fetch -
- remote.*.push
+ remote.*.push -
+ gui.recentrepo
{return 1}
*
{return 0}
diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl
index 4f57572..9f6926c 100644
--- a/git-gui/lib/choose_repository.tcl
+++ b/git-gui/lib/choose_repository.tcl
@@ -192,7 +192,7 @@ method _invoke_next {} {
proc _get_recentrepos {} {
set recent [list]
- foreach p [get_config gui.recentrepos] {
+ foreach p [get_config gui.recentrepo] {
if {[file isdirectory [file join $p .git]]} {
lappend recent $p
}
@@ -201,15 +201,18 @@ proc _get_recentrepos {} {
}
proc _append_recentrepos {path} {
- set recent [get_config gui.recentrepos]
- if {[lsearch $recent $path] < 0} {
- lappend recent $path
+ set recent [get_config gui.recentrepo]
+ if {[lsearch $recent $path] >= 0} {
+ return
}
+ lappend recent $path
if {[llength $recent] > 10} {
set recent [lrange $recent 1 end]
}
- regsub -all "\[{}\]" $recent {"} recent
- git config --global gui.recentrepos $recent
+ git config --global --unset-all gui.recentrepo
+ foreach p $recent {
+ git config --global --add gui.recentrepo $p
+ }
}
method _open_recent {} {
--
1.5.3.mingw.1.99.gdbfb3