This file documents the revision history for Perl extension Gitalist.
+0.004001 2013-03-15
+ - Depend on new Catalyst::Runtime and drop use of Catalyst::Controller::ActionRole
+ - Stop calling tags branches (Dennis Kaarsemaker)
+ - Stop breaking trees when submodules are encountered (Dennis Kaarsemaker)
+ - Correctly handle utf-8 encoded .git/description files (Dennis Kaarsemaker)
+ - Controller::ActionRole is dead (Tomas Doran)
+ - Add gitalist.psgi (Tomas Doran)
+
0.003009 2012-03-18
- Don't use MooseX::Types::ISO8601 to serialize DateTime objects as its
coercion function is now stricter than the object provided.
}, $FindBin::Bin . "/lib");
}
-requires 'Catalyst::Runtime' => '5.90006';
+requires 'Catalyst::Runtime' => '5.90013';
requires 'Catalyst::Plugin::ConfigLoader';
requires 'Catalyst::Plugin::StackTrace';
requires 'Catalyst::Plugin::Static::Simple';
requires 'Catalyst::Action::RenderView';
requires 'Catalyst::Action::REST';
requires 'Catalyst::Component::InstancePerContext';
-requires 'Catalyst::Controller::ActionRole';
requires 'Catalyst::View::Component::SubInclude' => '0.07';
requires 'Catalyst::View::TT' => '0.34';
requires 'Try::Tiny';
requires 'MooseX::Types::Common';
requires 'MooseX::Types::Path::Class';
requires 'MooseX::Types::DateTime' => '0.05';
+requires 'MooseX::Types::LoadableClass';
requires 'namespace::autoclean';
requires 'Git::PurePerl' => '0.47';
--- /dev/null
+use strict;
+use warnings;
+
+use Gitalist;
+
+my $app = Gitalist->apply_default_middlewares(Gitalist->psgi_app);
+$app;
+
SubRequest
/;
-our $VERSION = '0.003009';
+our $VERSION = '0.004001';
$VERSION = eval $VERSION;
__PACKAGE__->config(
use Moose;
use namespace::autoclean;
-BEGIN { extends 'Catalyst::Controller::ActionRole' }
+BEGIN { extends 'Catalyst::Controller' }
__PACKAGE__->meta->make_immutable;
+1;
+
;
$c->stash(
tree => $tree_obj,
- tree_list => $tree_obj->tree,
+ entries => $tree_obj->entries,
);
};
use Moose;
use Moose::Autobox;
use Digest::MD5 qw(md5_hex);
-use Gitalist::Utils qw/ age_string /;
+use Gitalist::Utils qw/ age_string mode_string /;
use namespace::autoclean;
$uri .= "?s=$size" if $size;
return $uri;
},
+ mode_string => sub {
+ return mode_string(oct shift);
+ }
);
}
use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/;
use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+ use Gitalist::Utils qw/mode_string/;
use overload '""' => '_to_string', fallback => 1;
# repository and sha1 are required initargs
}
method _build_modestr {
- return _mode_str($self->mode);
- }
-
- # via gitweb.pm circa line 1305
- use Fcntl ':mode';
- use constant {
- S_IFINVALID => 0030000,
- S_IFGITLINK => 0160000,
- };
-
- # submodule/subrepository, a commit object reference
- sub S_ISGITLINK($) {
- return (($_[0] & S_IFMT) == S_IFGITLINK)
- }
-
- # convert file mode in octal to symbolic file mode string
- sub _mode_str {
- my $mode = shift;
-
- if (S_ISGITLINK($mode)) {
- return 'm---------';
- } elsif (S_ISDIR($mode & S_IFMT)) {
- return 'drwxr-xr-x';
- } elsif ($^O ne 'MSWin32' and S_ISLNK($mode)) { # this is ENOLINKS country, we can't stop here!
- return 'lrwxrwxrwx';
- } elsif (S_ISREG($mode)) {
- # git cares only about the executable bit
- if ($mode & S_IXUSR) {
- return '-rwxr-xr-x';
- } else {
- return '-rw-r--r--';
- }
- } else {
- return '----------';
- }
+ return mode_string($self->mode);
}
} # end class
my @ret;
for my $line (split /\0/, $output) {
my ($mode, $type, $object, $file) = split /\s+/, $line, 4;
+ # Ignore commits, these represent submodules
+ next if $type eq 'commit';
my $class = 'Gitalist::Git::Object::' . ucfirst($type);
push @ret, $class->new( mode => oct $mode,
type => $type,
return \@ret;
}
+ method entries {
+ return $self->{_gpp_obj}->{directory_entries};
+ }
+
}
1;
my $description = "";
eval {
$description = $self->path->file('description')->slurp;
+ utf8::decode($description);
chomp $description;
};
$description = "Unnamed repository, edit the .git/description file to set a description"
our @EXPORT_OK = qw/
age_string
+ mode_string
/;
sub age_string {
return $_[0] !~ /^[[:print:]]+$ (?: \s ^[[:print:]]+$ )?/mx;
}
+# via gitweb.pm circa line 1305
+use Fcntl ':mode';
+use constant {
+ S_IFINVALID => 0030000,
+ S_IFGITLINK => 0160000,
+};
+
+# submodule/subrepository, a commit object reference
+sub S_ISGITLINK($) {
+ return (($_[0] & S_IFMT) == S_IFGITLINK)
+}
+
+# convert file mode in octal to symbolic file mode string
+sub mode_string {
+ my $mode = shift;
+
+ if (S_ISGITLINK($mode)) {
+ return 'm---------';
+ } elsif (S_ISDIR($mode & S_IFMT)) {
+ return 'drwxr-xr-x';
+ } elsif ($^O ne 'MSWin32' and S_ISLNK($mode)) { # this is ENOLINKS country, we can't stop here!
+ return 'lrwxrwxrwx';
+ } elsif (S_ISREG($mode)) {
+ # git cares only about the executable bit
+ if ($mode & S_IXUSR) {
+ return '-rwxr-xr-x';
+ } else {
+ return '-rw-r--r--';
+ }
+ } else {
+ return '----------';
+ }
+}
+
1;
__END__
# sort files and folders
SET tree_files = [];
SET tree_folders = [];
- FOREACH item IN tree_list;
- IF item.type == "blob";
+ FOREACH item IN entries;
+ IF item.mode != "40000";
tree_files.push(item);
ELSE;
tree_folders.push(item);
%]
[% BLOCK output_tree %]
- [% FOREACH item IN tree_type.sort('file') %]
+ [% FOREACH item IN tree_type.sort('filename') %]
<tr [% "class='invert'" IF counter % 2 %]>
- <td class='file-mode'>[% item.modestr %]</td>
+ <td class='file-mode'>[% c.stash.mode_string(item.mode) %]</td>
[%-
- action_type = item.type == 'tree' ? 'tree' : 'blob';
- action_for_link = item.type == 'tree' ? '/ref/tree' : '/ref/blob';
- blob_or_tree_link = c.uri_for_action(action_for_link, c.req.captures, c.req.args.to_path(item.file))
+ action_type = item.mode == '40000' ? 'tree' : 'blob';
+ action_for_link = item.mode == '40000' ? '/ref/tree' : '/ref/blob';
+ blob_or_tree_link = c.uri_for_action(action_for_link, c.req.captures, c.req.args.to_path(item.filename))
-%]
- <td class="file-name"><a href="[% blob_or_tree_link %]" class="[% item.type == 'blob' ? 'file' : 'folder' %]">[% item.file %]</a></td>
+ <td class="file-name"><a href="[% blob_or_tree_link %]" class="[% item.mode == '40000' ? 'folder' : 'file' %]">[% item.filename %]</a></td>
<td class='action-list'>
<a href="[% blob_or_tree_link %]">[% theact %]</a>
- [% IF item.type == 'blob' %]
- <a href="[% c.uri_for_action('/ref/blob', c.req.captures, c.req.args.to_path(item.file)) %]" title="Blob" class="button blob">Blob</a>
- <a href="[% c.uri_for_action('/ref/raw', c.req.captures, c.req.args.to_path(item.file)) %]" title="Raw" class="button raw">raw</a>
- <a href="[% c.uri_for_action('/ref/blame', c.req.captures, c.req.args.to_path(item.file)) %]" title="Blame" class="button blame">blame</a>
+ [% IF item.mode != '40000' %]
+ <a href="[% c.uri_for_action('/ref/blob', c.req.captures, c.req.args.to_path(item.filename)) %]" title="Blob" class="button blob">Blob</a>
+ <a href="[% c.uri_for_action('/ref/raw', c.req.captures, c.req.args.to_path(item.filename)) %]" title="Raw" class="button raw">raw</a>
+ <a href="[% c.uri_for_action('/ref/blame', c.req.captures, c.req.args.to_path(item.filename)) %]" title="Blame" class="button blame">blame</a>
[% END %]
- <a href="[% c.uri_for_action('/ref/history', c.req.captures, c.req.args.to_path(item.file)) %]" title="History (Short log)" class="button shortlog">Short log</a>
+ <a href="[% c.uri_for_action('/ref/history', c.req.captures, c.req.args.to_path(item.filename)) %]" title="History (Short log)" class="button shortlog">Short log</a>
</td>
- <td class="message"><span class='js-data'>[% c.req.args.to_path(item.file) %]</span>Loading commit info ...</td>
+ <td class="message"><span class='js-data'>[% c.req.args.to_path(item.filename) %]</span>Loading commit info ...</td>
</tr>
[% counter = counter + 1 %]
[% END %]
<tr class="header">
<[% cell %]>HEAD</[% cell %]>
<[% cell %]>Last change</[% cell %]>
- <[% cell %]>Branch</[% cell %]>
+ <[% cell %]>[% headtype || "Branch" %]</[% cell %]>
<[% cell %]>Actions</[% cell %]>
</tr>
[% END %]
-[% INCLUDE 'fragment/repository/heads.tt2' heads = tags %]
+[% INCLUDE 'fragment/repository/heads.tt2' heads = tags headtype="Tag" %]
{
my $contents = do { local $/; my $fh = $commit_obj->get_patch; <$fh> };
-ok(index($contents,
-'From 3f7567c7bdf7e7ebf410926493b92d398333116e Mon Sep 17 00:00:00 2001
-From: Florian Ragwitz <rafl@debian.org>
+like $contents, qr{^\QFrom 3f7567c7bdf7e7ebf410926493b92d398333116e Mon Sep 17 00:00:00 2001
+From: Florian Ragwitz <\Erafl[@]debian\Q.org>
Date: Tue, 6 Mar 2007 20:39:45 +0100
Subject: [PATCH] bar
---
- file1 | 2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
+ file1 |\E\s+2\Q +-
+ 1 \Efiles?\Q changed, 1 \Einsertions?\Q(+), 1 \Edeletions?\Q(-)
diff --git a/file1 b/file1
index 257cc56..5716ca5 100644
@@ -1 +1 @@
-foo
+bar
---') == 0, 'commit_obj->get_patch can return a patch')
- or warn("Got instead: $contents");
+--}, 'commit_obj->get_patch can return a patch';
}
# Note - 2 patches = 3 parts due to where we split.
repositoryformatversion = 0
filemode = true
bare = true
- ignorecase = true
+[remote "origin"]
+ url = /home/dbrook/dev/Gitalist/t/lib/repositories/./tmp
#!/bin/sh
#
# An example hook script to check the commit log message.
-# Called by git-commit with one argument, the name of the file
+# Called by "git commit" with one argument, the name of the file
# that has the commit message. The hook should exit with non-zero
# status after issuing an appropriate message if it wants to stop the
# commit. The hook is allowed to edit the commit message file.
# For example:
# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
-# see contrib/hooks/ for an sample, or uncomment the next line and
+# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".
#. /usr/share/doc/git-core/contrib/hooks/post-receive-email
#
# To enable this hook, rename this file to "post-update".
-exec git-update-server-info
+exec git update-server-info
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
-# Called by git-commit with no arguments. The hook should
+# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
# If you want to allow non-ascii filenames set this variable to true.
allownonascii=$(git config hooks.allownonascii)
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
- test "$(git diff --cached --name-only --diff-filter=A -z |
+ # Note that the use of brackets around a tr range is ok here, (it's
+ # even required, for portability to Solaris 10's /usr/bin/tr), since
+ # the square bracket bytes happen to fall in the designated range.
+ test "$(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0')"
then
- echo "Error: Attempt to add a non-ascii filename."
+ echo "Error: Attempt to add a non-ascii file name."
echo
- echo "This can cause problems if you want to work together"
- echo "with people on other platforms than you."
+ echo "This can cause problems if you want to work"
+ echo "with people on other platforms."
echo
- echo "To be portable it is adviseable to rename the file ..."
+ echo "To be portable it is advisable to rename the file ..."
echo
echo "If you know what you are doing you can disable this"
echo "check using:"
exit 1
fi
-if git-rev-parse --verify HEAD >/dev/null 2>&1
-then
- against=HEAD
-else
- # Initial commit: diff against an empty tree object
- against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-fi
-
exec git diff-index --check --cached $against --
#
# Copyright (c) 2006, 2008 Junio C Hamano
#
-# The "pre-rebase" hook is run just before "git-rebase" starts doing
+# The "pre-rebase" hook is run just before "git rebase" starts doing
# its job, and can prevent the command from running by exiting with
# non-zero status.
#
}
# Is topic fully merged to master?
-not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
if test -z "$not_in_master"
then
echo >&2 "$topic is fully merged to master; better remove it."
fi
# Is topic ever merged to next? If so you should not be rebasing it.
-only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
-only_next_2=`git-rev-list ^master ${publish} | sort`
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master ${publish} | sort`
if test "$only_next_1" = "$only_next_2"
then
- not_in_topic=`git-rev-list "^$topic" master`
+ not_in_topic=`git rev-list "^$topic" master`
if test -z "$not_in_topic"
then
echo >&2 "$topic is already up-to-date with master"
exit 0
fi
else
- not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
- perl -e '
+ not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+ /usr/bin/perl -e '
my $topic = $ARGV[0];
my $msg = "* $topic has commits already merged to public branch:\n";
my (%not_in_next) = map {
To compute (1):
- git-rev-list ^master ^topic next
- git-rev-list ^master next
+ git rev-list ^master ^topic next
+ git rev-list ^master next
if these match, topic has not merged in next at all.
To compute (2):
- git-rev-list master..topic
+ git rev-list master..topic
if this is empty, it is fully merged to "master".
#!/bin/sh
#
# An example hook script to prepare the commit log message.
-# Called by git-commit with the name of the file that has the
+# Called by "git commit" with the name of the file that has the
# commit message, followed by the description of the commit
# message's source. The hook's purpose is to edit the commit
# message file. If the hook fails with a non-zero status,
case "$2,$3" in
merge,)
- perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+ /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
# ,|template,)
-# perl -i.bak -pe '
+# /usr/bin/perl -i.bak -pe '
# print "\n" . `git diff --cached --name-status -r`
# if /^#/ && $first++ == 0' "$1" ;;
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
-# Called by git-receive-pack with arguments: refname sha1-old sha1-new
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
if [ "$newrev" = "$zero" ]; then
newrev_type=delete
else
- newrev_type=$(git-cat-file -t $newrev)
+ newrev_type=$(git cat-file -t $newrev)
fi
case "$refname","$newrev_type" in
-# git-ls-files --others --exclude-from=.git/info/exclude
+# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
--- /dev/null
+# pack-refs with: peeled
+14d4a45fe754bb3050e30b9395e93141e4fe9966 refs/heads/master