Projects are paths, so they should be sorted in pieces, not as a whole, so a/x will be come before a-b/x. Signed-off-by: Gustavo Sverzut Barbieri <barbieri@xxxxxxxxxxxxxx> --- New version that fix cmp_paths. Unlike I though initially, $#list reports the last element index, not the list length. Nonetheless the last component must be compared only if the list lengths are the same, otherwise we'll get $root/a/a.git before $root/b.git and sections will look ugly (group elements of the same level together). gitweb/gitweb.perl | 42 +++++++++++++++++++++++++++++++++++++----- 1 files changed, 37 insertions(+), 5 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 90cd99b..06c9901 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3574,17 +3574,45 @@ sub fill_project_list_info { return @projects; } +sub cmp_paths { + my ($a, $b) = @_; + my @la = split('/', $a); + my @lb = split('/', $b); + my $last; + + if ($#la < $#lb) { + $last = $#la; + } else { + $last = $#lb; + } + + for (my $i = 0; $i < $last; $i++) { + my $r = $la[$i] cmp $lb[$i]; + if ($r != 0) { + return $r; + } + } + + if ($#la == $#lb) { + return $la[$last] cmp $lb[$last]; + } else { + return $#la <=> $#lb; + } +} + # print 'sort by' <th> element, either sorting by $key if $name eq $order # (changing $list), or generating 'sort by $name' replay link otherwise sub print_sort_th { - my ($str_sort, $name, $order, $key, $header, $list) = @_; + my ($sort_mode, $name, $order, $key, $header, $list) = @_; $key ||= $name; $header ||= ucfirst($name); if ($order eq $name) { - if ($str_sort) { + if ($sort_mode == 2) { + @$list = sort {cmp_paths($a->{$key}, $b->{$key})} @$list; + } elsif ($sort_mode == 1) { @$list = sort {$a->{$key} cmp $b->{$key}} @$list; - } else { + } elsif ($sort_mode == 0) { @$list = sort {$a->{$key} <=> $b->{$key}} @$list; } print "<th>$header</th>\n"; @@ -3596,6 +3624,10 @@ sub print_sort_th { } } +sub print_sort_th_path { + print_sort_th(2, @_); +} + sub print_sort_th_str { print_sort_th(1, @_); } @@ -3620,8 +3652,8 @@ sub git_project_list_body { if ($check_forks) { print "<th></th>\n"; } - print_sort_th_str('project', $order, 'path', - 'Project', \@projects); + print_sort_th_path('project', $order, 'path', + 'Project', \@projects); print_sort_th_str('descr', $order, 'descr_long', 'Description', \@projects); print_sort_th_str('owner', $order, 'owner', -- 1.5.5.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html