* Re: [GIT PATCH] USB patches for 2.6.17
From: Linus Torvalds @ 2006-06-22 21:07 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: Andrew Morton, Greg KH, linux-kernel, git, linux-usb-devel
In-Reply-To: <Pine.LNX.4.64.0606221354070.6483@g5.osdl.org>
On Thu, 22 Jun 2006, Linus Torvalds wrote:
>
> After that, I'm not quite sure what you mean by "--dry-run". Do you mean
> to know about file-level conflicts? You do need to do the merge in order
> to know whether the conflicts can be resolved, but even without doing the
> merge you can look for _file_level_ conflicts by other means.
Btw, what you can always do is just
git pull <other-end>
.. look at the result ..
git reset --hard ORIG_HEAD
and you should be ok. It's obviously not a dry-run, it's more of a "do it
and then undo it", but hey, it should _work_.
(Look out for dirty state, though. "git pull" will happily pull into a
dirty tree if the changes don't actually affect any dirty files. The "git
reset --hard" thing will undo all dirty state, though).
Linus
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
^ permalink raw reply
* Re: What's in git.git and announcing v1.4.1-rc1
From: Jakub Narebski @ 2006-06-22 21:24 UTC (permalink / raw)
To: git; +Cc: linux-kernel
In-Reply-To: <Pine.LNX.4.64.0606221402140.6483@g5.osdl.org>
Linus Torvalds wrote:
>
>
> On Thu, 22 Jun 2006, Petr Baudis wrote:
>>
>> Isn't manually numbering the enum choices somewhat pointless, though?
>> (Actually makes it more difficult to do changes in it later.)
>
> Yeah, I just mindlessly followed Johannes' original scheme.
You might want to start at 0, just in case...
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* Re: What's in git.git and announcing v1.4.1-rc1
From: Petr Baudis @ 2006-06-22 21:28 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, linux-kernel
In-Reply-To: <e7f1pk$l1q$1@sea.gmane.org>
> >> Isn't manually numbering the enum choices somewhat pointless, though?
> >> (Actually makes it more difficult to do changes in it later.)
> >
> > Yeah, I just mindlessly followed Johannes' original scheme.
>
> You might want to start at 0, just in case...
C99 (6.7.2.2) guarantees the enumeration constants start at 0 if not
specified otherwise.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.
^ permalink raw reply
* [PATCH] Introduce Git.pm (v3)
From: Petr Baudis @ 2006-06-22 22:02 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch introduces a very basic and barebone Git.pm module
with a sketch of how the generic interface would look like;
most functions are missing, but this should give some good base.
I will continue expanding it.
Most desirable now is more careful error reporting, generic_in() for feeding
input to Git commands and the repository() constructor doing some poking
with git-rev-parse to get the git directory and subdirectory prefix.
Those three are basically the prerequisities for converting git-mv.
Currently Git.pm just wraps up exec()s of Git commands, but even that
is not trivial to get right and various Git perl scripts do it in
various inconsistent ways. In addition to Git.pm, there is now also
Git.xs which provides barebone Git.xs for directly interfacing with
libgit.a, and as an example providing the hash_object() function using
libgit.
This adds the Git module, integrates it to the build system and as
an example converts the git-fmt-merge-msg.perl script to it (the result
is not very impressive since its advantage is not quite apparent in this
one, but I just picked up the simplest Git user around).
The changes since v1 are:
* s/generic/command/ in the API, added command_pipe() and
changed behaviour of command() in the scalar context
* Added hash_object() and Git.xs providing the fast implementation
* Better error reporting
* Plenty of random minor stuff
It's a good thing v2 didn't make it to the list since it contained a huge
file which turns out that can be autogenerated at the build time, so v3
just changes that (and adds .gitignore file and makes some other minor
changes).
I consider this patch "stable" now. Further enhancements will be posted
as patches on top of this.
My current working state is available all the time at
http://pasky.or.cz/~xpasky/git-perl/Git.pm
and an irregularily updated API documentation is at
http://pasky.or.cz/~xpasky/git-perl/Git.html
Many thanks to Jakub Narebski, Junio and others for their feedback.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
Makefile | 12 +
git-fmt-merge-msg.perl | 10 +
perl/.gitignore | 7 +
perl/Git.pm | 401 ++++++++++++++++++++++++++++++++++++++++++++++++
perl/Git.xs | 60 +++++++
perl/Makefile.PL | 21 +++
6 files changed, 504 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index a5b6784..4d20b22 100644
--- a/Makefile
+++ b/Makefile
@@ -476,7 +476,8 @@ ### Build rules
all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk
-all:
+all: perl/Makefile
+ $(MAKE) -C perl
$(MAKE) -C templates
strip: $(PROGRAMS) git$X
@@ -508,7 +509,7 @@ common-cmds.h: Documentation/git-*.txt
$(patsubst %.perl,%,$(SCRIPT_PERL)) : % : %.perl
rm -f $@ $@+
- sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
+ sed -e '1s|#!.*perl\(.*\)|#!$(PERL_PATH_SQ)\1 -I'"$$(make -s -C perl instlibdir)"'|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
$@.perl >$@+
chmod +x $@+
@@ -594,6 +595,9 @@ XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare
rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS)
+perl/Makefile: perl/Git.pm perl/Makefile.PL
+ (cd perl && $(PERL_PATH) Makefile.PL PREFIX="$(prefix)" DEFINE="$(ALL_CFLAGS)" LIBS="$(LIBS)")
+
doc:
$(MAKE) -C Documentation all
@@ -649,6 +653,7 @@ install: all
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates install
+ $(MAKE) -C perl install
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
$(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
@@ -716,7 +721,8 @@ clean:
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
rm -f $(htmldocs).tar.gz $(manpages).tar.gz
$(MAKE) -C Documentation/ clean
- $(MAKE) -C templates clean
+ [ ! -e perl/Makefile ] || $(MAKE) -C perl/ clean
+ $(MAKE) -C templates/ clean
$(MAKE) -C t/ clean
rm -f GIT-VERSION-FILE GIT-CFLAGS
diff --git a/git-fmt-merge-msg.perl b/git-fmt-merge-msg.perl
index 5986e54..c32cafb 100755
--- a/git-fmt-merge-msg.perl
+++ b/git-fmt-merge-msg.perl
@@ -6,6 +6,9 @@ # Read .git/FETCH_HEAD and make a human
# by grouping branches and tags together to form a single line.
use strict;
+use Git;
+
+my $repo = Git->repository();
my @src;
my %src;
@@ -28,13 +31,12 @@ sub andjoin {
}
sub repoconfig {
- my ($val) = qx{git-repo-config --get merge.summary};
+ my ($val) = $repo->command_oneline('repo-config', '--get', 'merge.summary');
return $val;
}
sub current_branch {
- my ($bra) = qx{git-symbolic-ref HEAD};
- chomp($bra);
+ my ($bra) = $repo->command_oneline('symbolic-ref', 'HEAD');
$bra =~ s|^refs/heads/||;
if ($bra ne 'master') {
$bra = " into $bra";
@@ -47,7 +49,7 @@ sub current_branch {
sub shortlog {
my ($tip) = @_;
my @result;
- foreach ( qx{git-log --no-merges --topo-order --pretty=oneline $tip ^HEAD} ) {
+ foreach ($repo->command('log', '--no-merges', '--topo-order', '--pretty=oneline', $tip, '^HEAD')) {
s/^[0-9a-f]{40}\s+//;
push @result, $_;
}
diff --git a/perl/.gitignore b/perl/.gitignore
new file mode 100644
index 0000000..6d778f3
--- /dev/null
+++ b/perl/.gitignore
@@ -0,0 +1,7 @@
+Git.bs
+Git.c
+Makefile
+blib
+blibdirs
+pm_to_blib
+ppport.h
diff --git a/perl/Git.pm b/perl/Git.pm
new file mode 100644
index 0000000..4bb7c50
--- /dev/null
+++ b/perl/Git.pm
@@ -0,0 +1,401 @@
+=head1 NAME
+
+Git - Perl interface to the Git version control system
+
+=cut
+
+
+package Git;
+
+use strict;
+
+
+BEGIN {
+
+our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);
+
+# Totally unstable API.
+$VERSION = '0.01';
+
+
+=head1 SYNOPSIS
+
+ use Git;
+
+ my $version = Git::command_oneline('version');
+
+ Git::command_noisy('update-server-info');
+
+ my $repo = Git->repository (Directory => '/srv/git/cogito.git');
+
+
+ my @revs = $repo->command('rev-list', '--since=last monday', '--all');
+
+ my $fh = $repo->command_pipe('rev-list', '--since=last monday', '--all');
+ my $lastrev = <$fh>; chomp $lastrev;
+ close $fh; # You may want to test rev-list exit status here
+
+ my $lastrev = $repo->command_oneline('rev-list', '--all');
+
+=cut
+
+
+require Exporter;
+
+@ISA = qw(Exporter);
+
+@EXPORT = qw();
+
+# Methods which can be called as standalone functions as well:
+@EXPORT_OK = qw(command command_oneline command_pipe command_noisy);
+
+
+=head1 DESCRIPTION
+
+This module provides Perl scripts easy way to interface the Git version control
+system. The modules have an easy and well-tested way to call arbitrary Git
+commands; in the future, the interface will also provide specialized methods
+for doing easily operations which are not totally trivial to do over
+the generic command interface.
+
+While some commands can be executed outside of any context (e.g. 'version'
+or 'init-db'), most operations require a repository context, which in practice
+means getting an instance of the Git object using the repository() constructor.
+(In the future, we will also get a new_repository() constructor.) All commands
+called as methods of the object are then executed in the context of the
+repository.
+
+TODO: In the future, we might also do
+
+ my $subdir = $repo->subdir('Documentation');
+ # Gets called in the subdirectory context:
+ $subdir->command('status');
+
+ my $remoterepo = $repo->remote_repository (name => 'cogito', branch => 'master');
+ $remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
+ my @refs = $remoterepo->refs();
+
+So far, all functions just die if anything goes wrong. If you don't want that,
+make appropriate provisions to catch the possible deaths. Better error recovery
+mechanisms will be provided in the future.
+
+Currently, the module merely wraps calls to external Git tools. In the future,
+it will provide a much faster way to interact with Git by linking directly
+to libgit. This should be completely opaque to the user, though (performance
+increate nonwithstanding).
+
+=cut
+
+
+use Carp qw(carp croak);
+
+require XSLoader;
+XSLoader::load('Git', $VERSION);
+
+}
+
+
+=head1 CONSTRUCTORS
+
+=over 4
+
+=item repository ( OPTIONS )
+
+=item repository ( DIRECTORY )
+
+=item repository ()
+
+Construct a new repository object.
+C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+Possible options are:
+
+B<Repository> - Path to the Git repository.
+
+B<WorkingCopy> - Path to the associated working copy; not strictly required
+as many commands will happily crunch on a bare repository.
+
+B<Directory> - Path to the Git working directory in its usual setup. This
+is just for convenient setting of both C<Repository> and C<WorkingCopy>
+at once: If the directory as a C<.git> subdirectory, C<Repository> is pointed
+to the subdirectory and the directory is assumed to be the working copy.
+If the directory does not have the subdirectory, C<WorkingCopy> is left
+undefined and C<Repository> is pointed to the directory itself.
+
+B<GitPath> - Path to the C<git> binary executable. By default the C<$PATH>
+is searched for it.
+
+You should not use both C<Directory> and either of C<Repository> and
+C<WorkingCopy> - the results of that are undefined.
+
+Alternatively, a directory path may be passed as a single scalar argument
+to the constructor; it is equivalent to setting only the C<Directory> option
+field.
+
+Calling the constructor with no options whatsoever is equivalent to
+calling it with C<< Directory => '.' >>.
+
+=cut
+
+sub repository {
+ my $class = shift;
+ my @args = @_;
+ my %opts = ();
+ my $self;
+
+ if (defined $args[0]) {
+ if ($#args % 2 != 1) {
+ # Not a hash.
+ $#args == 0 or croak "bad usage";
+ %opts = (Directory => $args[0]);
+ } else {
+ %opts = @args;
+ }
+
+ if ($opts{Directory}) {
+ -d $opts{Directory} or croak "Directory not found: $!";
+ if (-d $opts{Directory}."/.git") {
+ # TODO: Might make this more clever
+ $opts{WorkingCopy} = $opts{Directory};
+ $opts{Repository} = $opts{Directory}."/.git";
+ } else {
+ $opts{Repository} = $opts{Directory};
+ }
+ delete $opts{Directory};
+ }
+ }
+
+ $self = { opts => \%opts };
+ bless $self, $class;
+}
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item command ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given Git C<COMMAND> (specify it without the 'git-'
+prefix), optionally with the specified extra C<ARGUMENTS>.
+
+The method can be called without any instance or on a specified Git repository
+(in that case the command will be run in the repository context).
+
+In scalar context, it returns all the command output in a single string
+(verbatim).
+
+In array context, it returns an array containing lines printed to the
+command's stdout (without trailing newlines).
+
+In both cases, the command's stdin and stderr are the same as the caller's.
+
+=cut
+
+sub command {
+ my $fh = command_pipe(@_);
+
+ if (not defined wantarray) {
+ _cmd_close($fh);
+
+ } elsif (not wantarray) {
+ local $/;
+ my $text = <$fh>;
+ _cmd_close($fh);
+ return $text;
+
+ } else {
+ my @lines = <$fh>;
+ _cmd_close($fh);
+ chomp @lines;
+ return @lines;
+ }
+}
+
+=item command_oneline ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command()
+does but always return a scalar string containing the first line
+of the command's standard output.
+
+=cut
+
+sub command_oneline {
+ my $fh = command_pipe(@_);
+
+ my $line = <$fh>;
+ _cmd_close($fh);
+
+ chomp $line;
+ return $line;
+}
+
+=item command_pipe ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command()
+does but return a pipe filehandle from which the command output can be
+read.
+
+=cut
+
+sub command_pipe {
+ my ($self, $cmd, @args) = _maybe_self(@_);
+
+ $cmd =~ /^[a-z0-9A-Z_-]+$/ or croak "bad command: $cmd";
+
+ my $pid = open(my $fh, "-|");
+ if (not defined $pid) {
+ croak "open failed: $!";
+ } elsif ($pid == 0) {
+ _cmd_exec($self, $cmd, @args);
+ }
+ return $fh;
+}
+
+=item command_noisy ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command() does but do not
+capture the command output - the standard output is not redirected and goes
+to the standard output of the caller application.
+
+While the method is called command_noisy(), you might want to as well use
+it for the most silent Git commands which you know will never pollute your
+stdout but you want to avoid the overhead of the pipe setup when calling them.
+
+The function returns only after the command has finished running.
+
+=cut
+
+sub command_noisy {
+ my ($self, $cmd, @args) = _maybe_self(@_);
+
+ $cmd =~ /^[a-z0-9A-Z_-]+$/ or croak "bad command: $cmd";
+
+ my $pid = fork;
+ if (not defined $pid) {
+ croak "fork failed: $!";
+ } elsif ($pid == 0) {
+ _cmd_exec($self, $cmd, @args);
+ }
+ if (waitpid($pid, 0) > 0 and $? != 0) {
+ croak "exit status: $?";
+ }
+}
+
+=item hash_object ( FILENAME [, TYPE ] )
+
+=item hash_object ( FILEHANDLE [, TYPE ] )
+
+Compute the SHA1 object id of the given C<FILENAME> (or data waiting in
+C<FILEHANDLE>) considering it is of the C<TYPE> object type (C<blob>
+(default), C<commit>, C<tree>).
+
+In case of C<FILEHANDLE> passed instead of file name, all the data
+available are read and hashed, and the filehandle is automatically
+closed. The file handle should be freshly opened - if you have already
+read anything from the file handle, the results are undefined (since
+this function works directly with the file descriptor and internal
+PerlIO buffering might have messed things up).
+
+The method can be called without any instance or on a specified Git repository,
+it makes zero difference.
+
+The function returns the SHA1 hash.
+
+Implementation of this function is very fast; no external command calls
+are involved.
+
+=cut
+
+# Implemented in Git.xs.
+
+
+=back
+
+=head1 TODO
+
+This is still fairly crude.
+We need some good way to report errors back except just dying.
+
+=head1 COPYRIGHT
+
+Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.
+
+This module is free software; it may be used, copied, modified
+and distributed under the terms of the GNU General Public Licence,
+either version 2, or (at your option) any later version.
+
+=cut
+
+
+# Take raw method argument list and return ($obj, @args) in case
+# the method was called upon an instance and (undef, @args) if
+# it was called directly.
+sub _maybe_self {
+ # This breaks inheritance. Oh well.
+ ref $_[0] eq 'Git' ? @_ : (undef, @_);
+}
+
+# When already in the subprocess, set up the appropriate state
+# for the given repository and execute the git command.
+sub _cmd_exec {
+ my ($self, @args) = @_;
+ if ($self) {
+ $self->{opts}->{Repository} and $ENV{'GIT_DIR'} = $self->{opts}->{Repository};
+ $self->{opts}->{WorkingCopy} and chdir($self->{opts}->{WorkingCopy});
+ }
+ my $git = $self->{opts}->{GitPath};
+ $git ||= 'git';
+ exec ($git, @args) or croak "exec failed: $!";
+}
+
+# Close pipe to a subprocess.
+sub _cmd_close {
+ my ($fh) = @_;
+ if (not close $fh) {
+ if ($!) {
+ # It's just close, no point in fatalities
+ carp "error closing pipe: $!";
+ } else {
+ croak "exit status: $?";
+ }
+ }
+}
+
+
+# Trickery for .xs routines: In order to avoid having some horrid
+# C code trying to do stuff with undefs and hashes, we gate all
+# xs calls through the following and in case we are being ran upon
+# an instance call a C part of the gate which will set up the
+# environment properly.
+sub _call_gate {
+ my $xsfunc = shift;
+ my ($self, @args) = _maybe_self(@_);
+
+ if (defined $self) {
+ # XXX: We ignore the WorkingCopy! To properly support
+ # that will require heavy changes in libgit.
+
+ # XXX: And we ignore everything else as well. libgit
+ # at least needs to be extended to let us specify
+ # the $GIT_DIR instead of looking it up in environment.
+ #xs_call_gate($self->{opts}->{Repository});
+ }
+
+ &$xsfunc(@args);
+}
+
+sub AUTOLOAD {
+ my $xsname;
+ our $AUTOLOAD;
+ ($xsname = $AUTOLOAD) =~ s/.*:://;
+ croak "&Git::$xsname not defined" if $xsname =~ /^xs_/;
+ $xsname = 'xs_'.$xsname;
+ _call_gate(\&$xsname, @_);
+}
+
+sub DESTROY { }
+
+
+1; # Famous last words
diff --git a/perl/Git.xs b/perl/Git.xs
new file mode 100644
index 0000000..33bb3ca
--- /dev/null
+++ b/perl/Git.xs
@@ -0,0 +1,60 @@
+/* By carefully stacking #includes here (even if WE don't really need them)
+ * we strive to make the thing actually compile. Git header files aren't very
+ * nice. Perl headers are one of the signs of the coming apocalypse. */
+#include <ctype.h>
+/* Ok, it hasn't been so bad so far. */
+
+/* libgit interface */
+#include "../cache.h"
+
+/* XS and Perl interface */
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "ppport.h"
+
+
+MODULE = Git PACKAGE = Git
+
+# /* TODO: xs_call_gate(). See Git.pm. */
+
+char *
+xs_hash_object(file, type = "blob")
+ SV *file;
+ char *type;
+CODE:
+ unsigned char sha1[20];
+
+ if (SvTYPE(file) == SVt_RV)
+ file = SvRV(file);
+
+ if (SvTYPE(file) == SVt_PVGV) {
+ /* Filehandle */
+ PerlIO *pio;
+
+ pio = IoIFP(sv_2io(file));
+ if (!pio)
+ croak("You passed me something weird - a dir glob?");
+ /* XXX: I just hope PerlIO didn't read anything from it yet.
+ * --pasky */
+ if (index_pipe(sha1, PerlIO_fileno(pio), type, 0))
+ croak("Unable to hash given filehandle");
+ /* Avoid any nasty surprises. */
+ Perl_io_close(sv_2io(file), 1);
+
+ } else {
+ /* String */
+ char *path = SvPV_nolen(file);
+ int fd = open(path, O_RDONLY);
+ struct stat st;
+
+ if (fd < 0 ||
+ fstat(fd, &st) < 0 ||
+ index_fd(sha1, fd, &st, 0, type))
+ croak("Unable to hash %s", path);
+ close(fd);
+ }
+ RETVAL = sha1_to_hex(sha1);
+OUTPUT:
+ RETVAL
diff --git a/perl/Makefile.PL b/perl/Makefile.PL
new file mode 100644
index 0000000..dd61056
--- /dev/null
+++ b/perl/Makefile.PL
@@ -0,0 +1,21 @@
+use ExtUtils::MakeMaker;
+
+sub MY::postamble {
+ return <<'MAKE_FRAG';
+instlibdir:
+ @echo $(INSTALLSITELIB)
+
+MAKE_FRAG
+}
+
+WriteMakefile(
+ NAME => 'Git',
+ VERSION_FROM => 'Git.pm',
+ MYEXTLIB => '../libgit.a',
+ INC => '-I. -I..',
+);
+
+
+use Devel::PPPort;
+
+-s 'ppport.h' or Devel::PPPort::WriteFile();
^ permalink raw reply related
* Re: What's in git.git and announcing v1.4.1-rc1
From: Junio C Hamano @ 2006-06-22 22:07 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0606221301500.5498@g5.osdl.org>
Linus Torvalds <torvalds@osdl.org> writes:
> On Thu, 22 Jun 2006, Junio C Hamano wrote:
>>
>> - diff --color (Johannes).
>
> I like colorized diffs, but let's face it, those particular color choices
> will make most people decide to pick out their eyes with a fondue fork.
Well, I admit I do not use colorized diffs myself. As a matter
of fact, I use specialized terminfo to disable coloring on my
terminal session, since fontifying in GNUS otherwise gives me
unreadable screen and I am too lazy to figure out how to turn it
off.
I do however usually test colored stuff with at least white and
black backgrounds,
> This patch does:
>
> - always reset the color _before_ printing out the newline.
Sorry, although I did notice this (interrupting a long diff, or
running it with "less -r" and quitting it would leave the
terminal in funny color), I did not bother to fix it.
> - default to red/green for old/new lines. That's the norm, I'd think.
OK.
> - instead of that eye-popping (and eye-ball-with-a-fondue-fork-popping)
> purple color for metadata, use bold-face for file headers, and cyan for
> the frag headers. I actually prefer the "gray background" for that, but
> it only works well in xterms, so COLOR_CYAN it is..
Replacing it with COLOR_GRAYBG did not work out too well with
either xterm nor kterm for me, although it did work under
gnome-terminal.
Cyan foreground color is unreadable on white background and that
was why I did magenta in my original patch, but it may be just
that I am color challenged in that spectrum.
^ permalink raw reply
* stgit: bunch of bugreports/wishes
From: Yann Dirson @ 2006-06-22 22:14 UTC (permalink / raw)
To: Catalin Marinas; +Cc: GIT list
Here are a number of problems I encountered while playing with
uncommit with 0.10:
- uncommit ignores grafts. This causes "uncommit -n" to through
"graft merges" without asking, and surely gives unexpected result
when a graft is used to change an ancestor rather than adding one.
- the previous behaviour causes strange interactions with merge
commits (eg. "stg show" cannot show the diff)
- uncommit could allow to go through a merge (indeed ignoring grafts
as it did was a gain of time for me, since it was in a couple of cases
precisely what I wanted to do ;). One possible interface to such a
feature would be to allow this if HEAD is the merge, and the branch to
follow is explicitely specified. The issue mentionned above seems to
indicate that when uncommitting a merge, a new commit for the
newly-uncommitted patch has to be created right away, to ensure it has
a single parent.
- uncommit could be more flexible to help with mass-uncommitting,
eg. with something like "--to <commit>" (to avoid counting manually),
or "--to-merge" to cleanly stop on first merge instead of failing
there. This may have an impact on how uncommits are numbered.
- uncommit synopsis is incomplete (lacks " | -n <n> <basename>")
- after mass-uncommitting, more help to look at the stack would be
needed. Eg. a "stg series" flag to print more commit info (author,
files), or to limit the listing to a given author (like "stg patches"
limits for a file).
Additionally, a couple of non-uncommit-related thing:
- when a push is not committed because of a conflict, looking at the
previous diff for the patch would help. Maybe something like "stg
show --old" ?
- the help string for push should say "patches", and possibly document
more precisely the syntax, something like:
--- a/stgit/commands/push.py
+++ b/stgit/commands/push.py
@@ -24,8 +24,8 @@ from stgit.utils import *
from stgit import stack, git
-help = 'push a patch on top of the series'
-usage = """%prog [options] [<patch1> [<patch2>...]]
+help = 'push patches on top of the series'
+usage = """%prog [options] [<patch1> [<patch2>...] | -n <n> <patchroot>]
Push a patch (defaulting to the first unapplied one) or range of
patches to the stack. The 'push' operation allows patch reordering by
- "push --undo" is not robust. On the occasion reproduced below, I
had to rollback the push myself by hand-modifying the stgit data,
which took me some effort. I'll have to gather precise info, but the
issue occurs on patch reordering, on a genuine conflict, and seems to
be involve a change to a non-existent file, when that file would have
been added by a non-applied patch originally below the one I attempted
to apply.
I do agree there is a conflict, but "push --undo" should definitely be
able to rollback in any case.
Here is the log:
========
Now at patch "patch9"
Pushing patch "patch10"...The merge failed during "push". Use "refresh"
after fixing the conflicts
stg push: GIT index merging failed (possible conflicts)
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
stg push: local changes in the tree. Use "refresh" to commit them
ydirson$ stg push --undo
Undoing the "patch10" push...stg push: ['git-diff-index', 'HEAD', 'path/to/the/file.java'] failed (fatal: ambiguous argument
'path/to/the/file.java': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions)
========
Best regards,
--
Yann Dirson <ydirson@altern.org> |
Debian-related: <dirson@debian.org> | Support Debian GNU/Linux:
| Freedom, Power, Stability, Gratis
http://ydirson.free.fr/ | Check <http://www.debian.org/>
^ permalink raw reply
* [PATCH] Git.pm: Implement Git::exec_path()
From: Petr Baudis @ 2006-06-22 22:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch implements Git::exec_path() (as a direct XS call).
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
perl/Git.pm | 20 +++++++++++++++++++-
perl/Git.xs | 10 ++++++++++
2 files changed, 29 insertions(+), 1 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 4bb7c50..516c065 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -47,7 +47,8 @@ require Exporter;
@EXPORT = qw();
# Methods which can be called as standalone functions as well:
-@EXPORT_OK = qw(command command_oneline command_pipe command_noisy);
+@EXPORT_OK = qw(command command_oneline command_pipe command_noisy
+ exec_path hash_object);
=head1 DESCRIPTION
@@ -213,6 +214,7 @@ sub command {
}
}
+
=item command_oneline ( COMMAND [, ARGUMENTS... ] )
Execute the given C<COMMAND> in the same way as command()
@@ -231,6 +233,7 @@ sub command_oneline {
return $line;
}
+
=item command_pipe ( COMMAND [, ARGUMENTS... ] )
Execute the given C<COMMAND> in the same way as command()
@@ -253,6 +256,7 @@ sub command_pipe {
return $fh;
}
+
=item command_noisy ( COMMAND [, ARGUMENTS... ] )
Execute the given C<COMMAND> in the same way as command() does but do not
@@ -283,6 +287,20 @@ sub command_noisy {
}
}
+
+=item exec_path ()
+
+Return path to the git sub-command executables (the same as
+C<git --exec-path>). Useful mostly only internally.
+
+Implementation of this function is very fast; no external command calls
+are involved.
+
+=cut
+
+# Implemented in Git.xs.
+
+
=item hash_object ( FILENAME [, TYPE ] )
=item hash_object ( FILEHANDLE [, TYPE ] )
diff --git a/perl/Git.xs b/perl/Git.xs
index 33bb3ca..d1f94a4 100644
--- a/perl/Git.xs
+++ b/perl/Git.xs
@@ -6,6 +6,7 @@ #include <ctype.h>
/* libgit interface */
#include "../cache.h"
+#include "../exec_cmd.h"
/* XS and Perl interface */
#include "EXTERN.h"
@@ -19,6 +20,15 @@ MODULE = Git PACKAGE = Git
# /* TODO: xs_call_gate(). See Git.pm. */
+
+const char *
+xs_exec_path()
+CODE:
+ RETVAL = git_exec_path();
+OUTPUT:
+ RETVAL
+
+
char *
xs_hash_object(file, type = "blob")
SV *file;
^ permalink raw reply related
* Re: What's in git.git and announcing v1.4.1-rc1
From: Junio C Hamano @ 2006-06-22 22:38 UTC (permalink / raw)
To: Linus Torvalds; +Cc: git
In-Reply-To: <7v7j38j144.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> writes:
> Well, I admit I do not use colorized diffs myself. As a matter
> of fact, I use specialized terminfo to disable coloring on my
> terminal session, since fontifying in GNUS otherwise gives me
> unreadable screen and I am too lazy to figure out how to turn it
> off.
>
> I do however usually test colored stuff with at least white and
> black backgrounds,
By the way, in the ancient history, in commit 3443546 you did:
--- a/Makefile
+++ b/Makefile
@@ -544,12 +545,18 @@ init-db.o: init-db.c
-DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $*.c
$(LIB_OBJS): $(LIB_H)
-$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H)
+$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIBS)
$(DIFF_OBJS): diffcore.h
$(LIB_FILE): $(LIB_OBJS)
$(AR) rcs $@ $(LIB_OBJS)
which we kept until today. This causes checkout-index.o and
friends to be recompiled when we touch diff.c (I do not mind
relinking git-checkout-index because libgit.a has changed, but
recompiling checkout-index.c is unneeded). I think this was
done to make sure anything that includes xdiff/*.h files via
"xdiff-interface.h" are recompiled when xdiff/*.h are changed,
so I am thinking about loosening it a bit to depend on our
headers and xdiff/*.h headers, perhaps like this:
diff --git a/Makefile b/Makefile
index a5b6784..e29e3fa 100644
--- a/Makefile
+++ b/Makefile
@@ -582,7 +582,7 @@ git-http-push$X: revision.o http.o http-
$(LIBS) $(CURL_LIBCURL) $(EXPAT_LIBEXPAT)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
-$(patsubst git-%$X,%.o,$(PROGRAMS)): $(GITLIBS)
+$(patsubst git-%$X,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
$(DIFF_OBJS): diffcore.h
$(LIB_FILE): $(LIB_OBJS)
diff --git a/diff.c b/diff.c
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
^ permalink raw reply related
* Resurrecting symlink problem
From: dormando @ 2006-06-22 23:00 UTC (permalink / raw)
To: git
Hey,
We have an issue with cogito/git and not being able to remove symlinks
from a central remote repo.
First try: cg-rm symlinks*
Complains that I'm trying to delete directories without the -r option.
So it's resolving the symlinks to the target directory.
git rm -f symlinks*
works. Symlinks are gone, push to repo, everything's happy.
However:
user A git rm -f's the symlinks, pushes to origin
user B cg-update's, then cg-commit's, cg-push's a one line change in an
unrelated file.
user A cg-update's, and the symlinks come back.
This happens over and over. They appear to disappear if cg-update does a
fast forward, but not if it does a merge. Any suggestions on how to
resolve this issue?
I'm still looking at what exactly is going on when user B does that
cg-update.
Thanks,
-Dormando
^ permalink raw reply
* Re: [PATCH] Introduce Git.pm (v3)
From: Junio C Hamano @ 2006-06-22 23:18 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060622220201.19132.67536.stgit@machine.or.cz>
Petr Baudis <pasky@suse.cz> writes:
> * Added hash_object() and Git.xs providing the fast implementation
> * Better error reporting
> * Plenty of random minor stuff
>
> It's a good thing v2 didn't make it to the list since it contained a huge
> file which turns out that can be autogenerated at the build time, so v3
> just changes that (and adds .gitignore file and makes some other minor
> changes).
>
> I consider this patch "stable" now. Further enhancements will be posted
> as patches on top of this.
Eek. It does not compile for me -- maybe there is more
dependencies that need to be listed in INSTALL file?
make -C perl
make[1]: Entering directory `/opt/git/git.git/perl'
cc -c -I. -I.. -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC "-I/usr/lib/perl/5.8/CORE" -O2 -Wall -Wdeclaration-after-statement -g -DSHA1_HEADER='<openssl/sha.h>' Git.c
Git.xs: In function 'XS_Git_xs_hash_object':
Git.xs:27: warning: ISO C90 forbids mixed declarations and code
Git.xs:44: warning: passing argument 1 of 'Perl_io_close' from incompatible pointer type
Git.xs:44: warning: passing argument 2 of 'Perl_io_close' makes pointer from integer without a cast
Git.xs:44: error: too few arguments to function 'Perl_io_close'
make[1]: *** [Git.o] Error 1
make[1]: Leaving directory `/opt/git/git.git/perl'
make: *** [all] Error 2
^ permalink raw reply
* [PATCH] Git.pm: Call external commands using execv_git_cmd()
From: Petr Baudis @ 2006-06-22 23:37 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Instead of explicitly using the git wrapper to call external commands,
use the execv_git_cmd() function which will directly call whatever
needs to be called. GitBin option becomes useless so drop it.
This actually means the exec_path() thing I planned to use worthless
internally, but Jakub wants it in anyway and I don't mind, so...
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
perl/Git.pm | 12 ++++++------
perl/Git.xs | 20 ++++++++++++++++++++
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 516c065..5b233ed 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -122,9 +122,6 @@ to the subdirectory and the directory is
If the directory does not have the subdirectory, C<WorkingCopy> is left
undefined and C<Repository> is pointed to the directory itself.
-B<GitPath> - Path to the C<git> binary executable. By default the C<$PATH>
-is searched for it.
-
You should not use both C<Directory> and either of C<Repository> and
C<WorkingCopy> - the results of that are undefined.
@@ -363,11 +360,14 @@ sub _cmd_exec {
$self->{opts}->{Repository} and $ENV{'GIT_DIR'} = $self->{opts}->{Repository};
$self->{opts}->{WorkingCopy} and chdir($self->{opts}->{WorkingCopy});
}
- my $git = $self->{opts}->{GitPath};
- $git ||= 'git';
- exec ($git, @args) or croak "exec failed: $!";
+ xs__execv_git_cmd(@args);
+ croak "exec failed: $!";
}
+# Execute the given Git command ($_[0]) with arguments ($_[1..])
+# by searching for it at proper places.
+# _execv_git_cmd(), implemented in Git.xs.
+
# Close pipe to a subprocess.
sub _cmd_close {
my ($fh) = @_;
diff --git a/perl/Git.xs b/perl/Git.xs
index d1f94a4..f94ee95 100644
--- a/perl/Git.xs
+++ b/perl/Git.xs
@@ -29,6 +29,26 @@ OUTPUT:
RETVAL
+void
+xs__execv_git_cmd(...)
+CODE:
+ const char **argv;
+ int i;
+
+ argv = malloc(sizeof(const char *) * (items + 1));
+ if (!argv)
+ croak("malloc failed");
+ for (i = 0; i < items; i++)
+ argv[i] = strdup(SvPV_nolen(ST(i)));
+ argv[i] = NULL;
+
+ execv_git_cmd(argv);
+
+ for (i = 0; i < items; i++)
+ if (argv[i])
+ free(argv[i]);
+ free(argv);
+
char *
xs_hash_object(file, type = "blob")
SV *file;
^ permalink raw reply related
* Re: [PATCH] Introduce Git.pm (v3)
From: Petr Baudis @ 2006-06-22 23:50 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7vlkrohj9p.fsf@assigned-by-dhcp.cox.net>
Dear diary, on Fri, Jun 23, 2006 at 01:18:10AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Petr Baudis <pasky@suse.cz> writes:
>
> > * Added hash_object() and Git.xs providing the fast implementation
> > * Better error reporting
> > * Plenty of random minor stuff
> >
> > It's a good thing v2 didn't make it to the list since it contained a huge
> > file which turns out that can be autogenerated at the build time, so v3
> > just changes that (and adds .gitignore file and makes some other minor
> > changes).
> >
> > I consider this patch "stable" now. Further enhancements will be posted
> > as patches on top of this.
>
> Eek. It does not compile for me -- maybe there is more
> dependencies that need to be listed in INSTALL file?
>
> make -C perl
> make[1]: Entering directory `/opt/git/git.git/perl'
> cc -c -I. -I.. -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC "-I/usr/lib/perl/5.8/CORE" -O2 -Wall -Wdeclaration-after-statement -g -DSHA1_HEADER='<openssl/sha.h>' Git.c
> Git.xs: In function 'XS_Git_xs_hash_object':
> Git.xs:27: warning: ISO C90 forbids mixed declarations and code
> Git.xs:44: warning: passing argument 1 of 'Perl_io_close' from incompatible pointer type
> Git.xs:44: warning: passing argument 2 of 'Perl_io_close' makes pointer from integer without a cast
> Git.xs:44: error: too few arguments to function 'Perl_io_close'
Oops, sorry. Apparently, I've digged too deep and unleashed a monster of
unstable API. Now I've finally discovered perlapio(1) and know I
should've just called PerlIO_close(). Below comes a fixed patch, I
didn't bother to bump the version number.
---
[PATCH] Introduce Git.pm (v3)
This patch introduces a very basic and barebone Git.pm module
with a sketch of how the generic interface would look like;
most functions are missing, but this should give some good base.
I will continue expanding it.
Most desirable now is more careful error reporting, generic_in() for feeding
input to Git commands and the repository() constructor doing some poking
with git-rev-parse to get the git directory and subdirectory prefix.
Those three are basically the prerequisities for converting git-mv.
Currently Git.pm just wraps up exec()s of Git commands, but even that
is not trivial to get right and various Git perl scripts do it in
various inconsistent ways. In addition to Git.pm, there is now also
Git.xs which provides barebone Git.xs for directly interfacing with
libgit.a, and as an example providing the hash_object() function using
libgit.
This adds the Git module, integrates it to the build system and as
an example converts the git-fmt-merge-msg.perl script to it (the result
is not very impressive since its advantage is not quite apparent in this
one, but I just picked up the simplest Git user around).
The changes since v1 are:
* s/generic/command/ in the API, added command_pipe() and
changed behaviour of command() in the scalar context
* Added hash_object() and Git.xs providing the fast implementation
* Better error reporting
* Plenty of random minor stuff
It's a good thing v2 didn't make it to the list since it contained a huge
file which turns out that can be autogenerated at the build time, so v3
just changes that (and adds .gitignore file and makes some other minor
changes).
I consider this patch "stable" now. Further enhancements will be posted
as patches on top of this.
My current working state is available all the time at
http://pasky.or.cz/~xpasky/git-perl/Git.pm
and an irregularily updated API documentation is at
http://pasky.or.cz/~xpasky/git-perl/Git.html
Many thanks to Jakub Narebski, Junio and others for their feedback.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
Makefile | 12 +
git-fmt-merge-msg.perl | 10 +
perl/.gitignore | 7 +
perl/Git.pm | 401 ++++++++++++++++++++++++++++++++++++++++++++++++
perl/Git.xs | 60 +++++++
perl/Makefile.PL | 21 +++
6 files changed, 504 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index a5b6784..4d20b22 100644
--- a/Makefile
+++ b/Makefile
@@ -476,7 +476,8 @@ ### Build rules
all: $(ALL_PROGRAMS) $(BUILT_INS) git$X gitk
-all:
+all: perl/Makefile
+ $(MAKE) -C perl
$(MAKE) -C templates
strip: $(PROGRAMS) git$X
@@ -508,7 +509,7 @@ common-cmds.h: Documentation/git-*.txt
$(patsubst %.perl,%,$(SCRIPT_PERL)) : % : %.perl
rm -f $@ $@+
- sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
+ sed -e '1s|#!.*perl\(.*\)|#!$(PERL_PATH_SQ)\1 -I'"$$(make -s -C perl instlibdir)"'|' \
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
$@.perl >$@+
chmod +x $@+
@@ -594,6 +595,9 @@ XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare
rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS)
+perl/Makefile: perl/Git.pm perl/Makefile.PL
+ (cd perl && $(PERL_PATH) Makefile.PL PREFIX="$(prefix)" DEFINE="$(ALL_CFLAGS)" LIBS="$(LIBS)")
+
doc:
$(MAKE) -C Documentation all
@@ -649,6 +653,7 @@ install: all
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)'
$(MAKE) -C templates install
+ $(MAKE) -C perl install
$(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
$(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
@@ -716,7 +721,8 @@ clean:
rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
rm -f $(htmldocs).tar.gz $(manpages).tar.gz
$(MAKE) -C Documentation/ clean
- $(MAKE) -C templates clean
+ [ ! -e perl/Makefile ] || $(MAKE) -C perl/ clean
+ $(MAKE) -C templates/ clean
$(MAKE) -C t/ clean
rm -f GIT-VERSION-FILE GIT-CFLAGS
diff --git a/git-fmt-merge-msg.perl b/git-fmt-merge-msg.perl
index 5986e54..c32cafb 100755
--- a/git-fmt-merge-msg.perl
+++ b/git-fmt-merge-msg.perl
@@ -6,6 +6,9 @@ # Read .git/FETCH_HEAD and make a human
# by grouping branches and tags together to form a single line.
use strict;
+use Git;
+
+my $repo = Git->repository();
my @src;
my %src;
@@ -28,13 +31,12 @@ sub andjoin {
}
sub repoconfig {
- my ($val) = qx{git-repo-config --get merge.summary};
+ my ($val) = $repo->command_oneline('repo-config', '--get', 'merge.summary');
return $val;
}
sub current_branch {
- my ($bra) = qx{git-symbolic-ref HEAD};
- chomp($bra);
+ my ($bra) = $repo->command_oneline('symbolic-ref', 'HEAD');
$bra =~ s|^refs/heads/||;
if ($bra ne 'master') {
$bra = " into $bra";
@@ -47,7 +49,7 @@ sub current_branch {
sub shortlog {
my ($tip) = @_;
my @result;
- foreach ( qx{git-log --no-merges --topo-order --pretty=oneline $tip ^HEAD} ) {
+ foreach ($repo->command('log', '--no-merges', '--topo-order', '--pretty=oneline', $tip, '^HEAD')) {
s/^[0-9a-f]{40}\s+//;
push @result, $_;
}
diff --git a/perl/.gitignore b/perl/.gitignore
new file mode 100644
index 0000000..6d778f3
--- /dev/null
+++ b/perl/.gitignore
@@ -0,0 +1,7 @@
+Git.bs
+Git.c
+Makefile
+blib
+blibdirs
+pm_to_blib
+ppport.h
diff --git a/perl/Git.pm b/perl/Git.pm
new file mode 100644
index 0000000..4bb7c50
--- /dev/null
+++ b/perl/Git.pm
@@ -0,0 +1,401 @@
+=head1 NAME
+
+Git - Perl interface to the Git version control system
+
+=cut
+
+
+package Git;
+
+use strict;
+
+
+BEGIN {
+
+our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);
+
+# Totally unstable API.
+$VERSION = '0.01';
+
+
+=head1 SYNOPSIS
+
+ use Git;
+
+ my $version = Git::command_oneline('version');
+
+ Git::command_noisy('update-server-info');
+
+ my $repo = Git->repository (Directory => '/srv/git/cogito.git');
+
+
+ my @revs = $repo->command('rev-list', '--since=last monday', '--all');
+
+ my $fh = $repo->command_pipe('rev-list', '--since=last monday', '--all');
+ my $lastrev = <$fh>; chomp $lastrev;
+ close $fh; # You may want to test rev-list exit status here
+
+ my $lastrev = $repo->command_oneline('rev-list', '--all');
+
+=cut
+
+
+require Exporter;
+
+@ISA = qw(Exporter);
+
+@EXPORT = qw();
+
+# Methods which can be called as standalone functions as well:
+@EXPORT_OK = qw(command command_oneline command_pipe command_noisy);
+
+
+=head1 DESCRIPTION
+
+This module provides Perl scripts easy way to interface the Git version control
+system. The modules have an easy and well-tested way to call arbitrary Git
+commands; in the future, the interface will also provide specialized methods
+for doing easily operations which are not totally trivial to do over
+the generic command interface.
+
+While some commands can be executed outside of any context (e.g. 'version'
+or 'init-db'), most operations require a repository context, which in practice
+means getting an instance of the Git object using the repository() constructor.
+(In the future, we will also get a new_repository() constructor.) All commands
+called as methods of the object are then executed in the context of the
+repository.
+
+TODO: In the future, we might also do
+
+ my $subdir = $repo->subdir('Documentation');
+ # Gets called in the subdirectory context:
+ $subdir->command('status');
+
+ my $remoterepo = $repo->remote_repository (name => 'cogito', branch => 'master');
+ $remoterepo ||= Git->remote_repository ('http://git.or.cz/cogito.git/');
+ my @refs = $remoterepo->refs();
+
+So far, all functions just die if anything goes wrong. If you don't want that,
+make appropriate provisions to catch the possible deaths. Better error recovery
+mechanisms will be provided in the future.
+
+Currently, the module merely wraps calls to external Git tools. In the future,
+it will provide a much faster way to interact with Git by linking directly
+to libgit. This should be completely opaque to the user, though (performance
+increate nonwithstanding).
+
+=cut
+
+
+use Carp qw(carp croak);
+
+require XSLoader;
+XSLoader::load('Git', $VERSION);
+
+}
+
+
+=head1 CONSTRUCTORS
+
+=over 4
+
+=item repository ( OPTIONS )
+
+=item repository ( DIRECTORY )
+
+=item repository ()
+
+Construct a new repository object.
+C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+Possible options are:
+
+B<Repository> - Path to the Git repository.
+
+B<WorkingCopy> - Path to the associated working copy; not strictly required
+as many commands will happily crunch on a bare repository.
+
+B<Directory> - Path to the Git working directory in its usual setup. This
+is just for convenient setting of both C<Repository> and C<WorkingCopy>
+at once: If the directory as a C<.git> subdirectory, C<Repository> is pointed
+to the subdirectory and the directory is assumed to be the working copy.
+If the directory does not have the subdirectory, C<WorkingCopy> is left
+undefined and C<Repository> is pointed to the directory itself.
+
+B<GitPath> - Path to the C<git> binary executable. By default the C<$PATH>
+is searched for it.
+
+You should not use both C<Directory> and either of C<Repository> and
+C<WorkingCopy> - the results of that are undefined.
+
+Alternatively, a directory path may be passed as a single scalar argument
+to the constructor; it is equivalent to setting only the C<Directory> option
+field.
+
+Calling the constructor with no options whatsoever is equivalent to
+calling it with C<< Directory => '.' >>.
+
+=cut
+
+sub repository {
+ my $class = shift;
+ my @args = @_;
+ my %opts = ();
+ my $self;
+
+ if (defined $args[0]) {
+ if ($#args % 2 != 1) {
+ # Not a hash.
+ $#args == 0 or croak "bad usage";
+ %opts = (Directory => $args[0]);
+ } else {
+ %opts = @args;
+ }
+
+ if ($opts{Directory}) {
+ -d $opts{Directory} or croak "Directory not found: $!";
+ if (-d $opts{Directory}."/.git") {
+ # TODO: Might make this more clever
+ $opts{WorkingCopy} = $opts{Directory};
+ $opts{Repository} = $opts{Directory}."/.git";
+ } else {
+ $opts{Repository} = $opts{Directory};
+ }
+ delete $opts{Directory};
+ }
+ }
+
+ $self = { opts => \%opts };
+ bless $self, $class;
+}
+
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item command ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given Git C<COMMAND> (specify it without the 'git-'
+prefix), optionally with the specified extra C<ARGUMENTS>.
+
+The method can be called without any instance or on a specified Git repository
+(in that case the command will be run in the repository context).
+
+In scalar context, it returns all the command output in a single string
+(verbatim).
+
+In array context, it returns an array containing lines printed to the
+command's stdout (without trailing newlines).
+
+In both cases, the command's stdin and stderr are the same as the caller's.
+
+=cut
+
+sub command {
+ my $fh = command_pipe(@_);
+
+ if (not defined wantarray) {
+ _cmd_close($fh);
+
+ } elsif (not wantarray) {
+ local $/;
+ my $text = <$fh>;
+ _cmd_close($fh);
+ return $text;
+
+ } else {
+ my @lines = <$fh>;
+ _cmd_close($fh);
+ chomp @lines;
+ return @lines;
+ }
+}
+
+=item command_oneline ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command()
+does but always return a scalar string containing the first line
+of the command's standard output.
+
+=cut
+
+sub command_oneline {
+ my $fh = command_pipe(@_);
+
+ my $line = <$fh>;
+ _cmd_close($fh);
+
+ chomp $line;
+ return $line;
+}
+
+=item command_pipe ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command()
+does but return a pipe filehandle from which the command output can be
+read.
+
+=cut
+
+sub command_pipe {
+ my ($self, $cmd, @args) = _maybe_self(@_);
+
+ $cmd =~ /^[a-z0-9A-Z_-]+$/ or croak "bad command: $cmd";
+
+ my $pid = open(my $fh, "-|");
+ if (not defined $pid) {
+ croak "open failed: $!";
+ } elsif ($pid == 0) {
+ _cmd_exec($self, $cmd, @args);
+ }
+ return $fh;
+}
+
+=item command_noisy ( COMMAND [, ARGUMENTS... ] )
+
+Execute the given C<COMMAND> in the same way as command() does but do not
+capture the command output - the standard output is not redirected and goes
+to the standard output of the caller application.
+
+While the method is called command_noisy(), you might want to as well use
+it for the most silent Git commands which you know will never pollute your
+stdout but you want to avoid the overhead of the pipe setup when calling them.
+
+The function returns only after the command has finished running.
+
+=cut
+
+sub command_noisy {
+ my ($self, $cmd, @args) = _maybe_self(@_);
+
+ $cmd =~ /^[a-z0-9A-Z_-]+$/ or croak "bad command: $cmd";
+
+ my $pid = fork;
+ if (not defined $pid) {
+ croak "fork failed: $!";
+ } elsif ($pid == 0) {
+ _cmd_exec($self, $cmd, @args);
+ }
+ if (waitpid($pid, 0) > 0 and $? != 0) {
+ croak "exit status: $?";
+ }
+}
+
+=item hash_object ( FILENAME [, TYPE ] )
+
+=item hash_object ( FILEHANDLE [, TYPE ] )
+
+Compute the SHA1 object id of the given C<FILENAME> (or data waiting in
+C<FILEHANDLE>) considering it is of the C<TYPE> object type (C<blob>
+(default), C<commit>, C<tree>).
+
+In case of C<FILEHANDLE> passed instead of file name, all the data
+available are read and hashed, and the filehandle is automatically
+closed. The file handle should be freshly opened - if you have already
+read anything from the file handle, the results are undefined (since
+this function works directly with the file descriptor and internal
+PerlIO buffering might have messed things up).
+
+The method can be called without any instance or on a specified Git repository,
+it makes zero difference.
+
+The function returns the SHA1 hash.
+
+Implementation of this function is very fast; no external command calls
+are involved.
+
+=cut
+
+# Implemented in Git.xs.
+
+
+=back
+
+=head1 TODO
+
+This is still fairly crude.
+We need some good way to report errors back except just dying.
+
+=head1 COPYRIGHT
+
+Copyright 2006 by Petr Baudis E<lt>pasky@suse.czE<gt>.
+
+This module is free software; it may be used, copied, modified
+and distributed under the terms of the GNU General Public Licence,
+either version 2, or (at your option) any later version.
+
+=cut
+
+
+# Take raw method argument list and return ($obj, @args) in case
+# the method was called upon an instance and (undef, @args) if
+# it was called directly.
+sub _maybe_self {
+ # This breaks inheritance. Oh well.
+ ref $_[0] eq 'Git' ? @_ : (undef, @_);
+}
+
+# When already in the subprocess, set up the appropriate state
+# for the given repository and execute the git command.
+sub _cmd_exec {
+ my ($self, @args) = @_;
+ if ($self) {
+ $self->{opts}->{Repository} and $ENV{'GIT_DIR'} = $self->{opts}->{Repository};
+ $self->{opts}->{WorkingCopy} and chdir($self->{opts}->{WorkingCopy});
+ }
+ my $git = $self->{opts}->{GitPath};
+ $git ||= 'git';
+ exec ($git, @args) or croak "exec failed: $!";
+}
+
+# Close pipe to a subprocess.
+sub _cmd_close {
+ my ($fh) = @_;
+ if (not close $fh) {
+ if ($!) {
+ # It's just close, no point in fatalities
+ carp "error closing pipe: $!";
+ } else {
+ croak "exit status: $?";
+ }
+ }
+}
+
+
+# Trickery for .xs routines: In order to avoid having some horrid
+# C code trying to do stuff with undefs and hashes, we gate all
+# xs calls through the following and in case we are being ran upon
+# an instance call a C part of the gate which will set up the
+# environment properly.
+sub _call_gate {
+ my $xsfunc = shift;
+ my ($self, @args) = _maybe_self(@_);
+
+ if (defined $self) {
+ # XXX: We ignore the WorkingCopy! To properly support
+ # that will require heavy changes in libgit.
+
+ # XXX: And we ignore everything else as well. libgit
+ # at least needs to be extended to let us specify
+ # the $GIT_DIR instead of looking it up in environment.
+ #xs_call_gate($self->{opts}->{Repository});
+ }
+
+ &$xsfunc(@args);
+}
+
+sub AUTOLOAD {
+ my $xsname;
+ our $AUTOLOAD;
+ ($xsname = $AUTOLOAD) =~ s/.*:://;
+ croak "&Git::$xsname not defined" if $xsname =~ /^xs_/;
+ $xsname = 'xs_'.$xsname;
+ _call_gate(\&$xsname, @_);
+}
+
+sub DESTROY { }
+
+
+1; # Famous last words
diff --git a/perl/Git.xs b/perl/Git.xs
new file mode 100644
index 0000000..3799ee9
--- /dev/null
+++ b/perl/Git.xs
@@ -0,0 +1,60 @@
+/* By carefully stacking #includes here (even if WE don't really need them)
+ * we strive to make the thing actually compile. Git header files aren't very
+ * nice. Perl headers are one of the signs of the coming apocalypse. */
+#include <ctype.h>
+/* Ok, it hasn't been so bad so far. */
+
+/* libgit interface */
+#include "../cache.h"
+
+/* XS and Perl interface */
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "ppport.h"
+
+
+MODULE = Git PACKAGE = Git
+
+# /* TODO: xs_call_gate(). See Git.pm. */
+
+char *
+xs_hash_object(file, type = "blob")
+ SV *file;
+ char *type;
+CODE:
+ unsigned char sha1[20];
+
+ if (SvTYPE(file) == SVt_RV)
+ file = SvRV(file);
+
+ if (SvTYPE(file) == SVt_PVGV) {
+ /* Filehandle */
+ PerlIO *pio;
+
+ pio = IoIFP(sv_2io(file));
+ if (!pio)
+ croak("You passed me something weird - a dir glob?");
+ /* XXX: I just hope PerlIO didn't read anything from it yet.
+ * --pasky */
+ if (index_pipe(sha1, PerlIO_fileno(pio), type, 0))
+ croak("Unable to hash given filehandle");
+ /* Avoid any nasty surprises. */
+ PerlIO_close(pio);
+
+ } else {
+ /* String */
+ char *path = SvPV_nolen(file);
+ int fd = open(path, O_RDONLY);
+ struct stat st;
+
+ if (fd < 0 ||
+ fstat(fd, &st) < 0 ||
+ index_fd(sha1, fd, &st, 0, type))
+ croak("Unable to hash %s", path);
+ close(fd);
+ }
+ RETVAL = sha1_to_hex(sha1);
+OUTPUT:
+ RETVAL
diff --git a/perl/Makefile.PL b/perl/Makefile.PL
new file mode 100644
index 0000000..dd61056
--- /dev/null
+++ b/perl/Makefile.PL
@@ -0,0 +1,21 @@
+use ExtUtils::MakeMaker;
+
+sub MY::postamble {
+ return <<'MAKE_FRAG';
+instlibdir:
+ @echo $(INSTALLSITELIB)
+
+MAKE_FRAG
+}
+
+WriteMakefile(
+ NAME => 'Git',
+ VERSION_FROM => 'Git.pm',
+ MYEXTLIB => '../libgit.a',
+ INC => '-I. -I..',
+);
+
+
+use Devel::PPPort;
+
+-s 'ppport.h' or Devel::PPPort::WriteFile();
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.
^ permalink raw reply related
* [PATCH] Git.pm: Implement Git::version()
From: Petr Baudis @ 2006-06-22 23:59 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Git::version() returns the Git version string.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
Makefile | 5 ++++-
perl/Git.pm | 12 ++++++++++++
perl/Git.xs | 8 ++++++++
3 files changed, 24 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index 4d20b22..7842195 100644
--- a/Makefile
+++ b/Makefile
@@ -596,7 +596,10 @@ XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare
perl/Makefile: perl/Git.pm perl/Makefile.PL
- (cd perl && $(PERL_PATH) Makefile.PL PREFIX="$(prefix)" DEFINE="$(ALL_CFLAGS)" LIBS="$(LIBS)")
+ (cd perl && $(PERL_PATH) Makefile.PL \
+ PREFIX="$(prefix)" \
+ DEFINE="$(ALL_CFLAGS) -DGIT_VERSION=\\\"$(GIT_VERSION)\\\"" \
+ LIBS="$(LIBS)")
doc:
$(MAKE) -C Documentation all
diff --git a/perl/Git.pm b/perl/Git.pm
index 5b233ed..3f85000 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -285,6 +285,18 @@ sub command_noisy {
}
+=item version ()
+
+Return the Git version in use.
+
+Implementation of this function is very fast; no external command calls
+are involved.
+
+=cut
+
+# Implemented in Git.xs.
+
+
=item exec_path ()
Return path to the git sub-command executables (the same as
diff --git a/perl/Git.xs b/perl/Git.xs
index 792dc6d..4d57685 100644
--- a/perl/Git.xs
+++ b/perl/Git.xs
@@ -22,6 +22,14 @@ # /* TODO: xs_call_gate(). See Git.pm. *
const char *
+xs_version()
+CODE:
+ RETVAL = GIT_VERSION;
+OUTPUT:
+ RETVAL
+
+
+const char *
xs_exec_path()
CODE:
RETVAL = git_exec_path();
^ permalink raw reply related
* Re: [PATCH] Git.pm: Call external commands using execv_git_cmd()
From: Junio C Hamano @ 2006-06-23 0:08 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060622233752.29122.78856.stgit@machine.or.cz>
Petr Baudis <pasky@suse.cz> writes:
> Instead of explicitly using the git wrapper to call external commands,
> use the execv_git_cmd() function which will directly call whatever
> needs to be called. GitBin option becomes useless so drop it.
I think you meant GitPath here.
^ permalink raw reply
* Re: [PATCH] Introduce Git.pm (v3)
From: Junio C Hamano @ 2006-06-23 0:22 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060622235017.GH21864@pasky.or.cz>
Petr Baudis <pasky@suse.cz> writes:
>> Eek. It does not compile for me -- maybe there is more
>> dependencies that need to be listed in INSTALL file?
>> ...
>> Git.xs: In function 'XS_Git_xs_hash_object':
>> Git.xs:27: warning: ISO C90 forbids mixed declarations and code
>> Git.xs:44: warning: passing argument 1 of 'Perl_io_close' from incompatible pointer type
>> Git.xs:44: warning: passing argument 2 of 'Perl_io_close' makes pointer from integer without a cast
>> Git.xs:44: error: too few arguments to function 'Perl_io_close'
>
> Oops, sorry. Apparently, I've digged too deep and unleashed a monster of
> unstable API. Now I've finally discovered perlapio(1) and know I
> should've just called PerlIO_close(). Below comes a fixed patch, I
> didn't bother to bump the version number.
Thanks; it compiles now with a few more glitches.
/usr/bin/perl /usr/share/perl/5.8/ExtUtils/xsubpp \
-typemap /usr/share/perl/5.8/ExtUtils/typemap Git.xs > Git.xsc && \
mv Git.xsc Git.c
Please specify prototyping behavior for Git.xs (see perlxs manual)
Says xsubpp.
cc -c -I. -I.. -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS \
-DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include \
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 \
-DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC \
"-I/usr/lib/perl/5.8/CORE" -Wall
-Wdeclaration-after-statement \
-g -DSHA1_HEADER='<openssl/sha.h>' \
-DGIT_VERSION=\"1.4.1.rc1.g01a1\" Git.c
Git.xs: In function 'XS_Git_xs__execv_git_cmd':
Git.xs:57: warning: passing argument 1 of 'free' discards qualifiers from pointer target type
Git.xs: In function 'XS_Git_xs_hash_object':
Git.xs:65: warning: ISO C90 forbids mixed declarations and code
I usually compile with -Wdeclaration-after-statement so I
probably get some more warnings than you saw; it probably is
primarily xsubpp's fault, but you could work it around by having
CODE block to be inside an extra set of braces {}. Constness
reduction of free() is a bit annoying from the point of view of
the coder who has to cast away constness, so I won't be too
strict about that, but it would be nicer if we did not have to
see the warnings.
rm -f blib/arch/auto/Git/Git.so
cc -shared -L/usr/local/lib Git.o -o blib/arch/auto/Git/Git.so ../libgit.a \
-lz -lcrypto \
/usr/bin/ld: ../libgit.a(exec_cmd.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
../libgit.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make[1]: *** [blib/arch/auto/Git/Git.so] Error 1
This is a real killer. If we compile everything with -fPIC,
this goes away, but I do not think we want -fPIC for the core
level tools. At least not until we are ready to do libgit.so.
^ permalink raw reply
* git-format-patch builtin isn't using git-cherry?
From: Martin Langhoff @ 2006-06-23 0:32 UTC (permalink / raw)
To: git
I used to rely on git-format-patch to be calling git-cherry in the bg,
so that I'd know that the obviously merged patches were upstream
alredy. It doesn't seem to do it any more.
Reading cmd_format_patch() in builtin-log.c, it seems to have lost
that magic that made it so useful... :( Can a kind soul that speaks C
fluently help me out here?
(The new format-patch gives me 180 patches to merge/rebase, where the
old one tells me there's only 51. guess which one I prefer ;-) )
cheers,
m
^ permalink raw reply
* Re: Added macro support to qgit
From: Pavel Roskin @ 2006-06-23 1:00 UTC (permalink / raw)
To: Marco Costalba; +Cc: git
In-Reply-To: <e5bfff550606220704q568d8345o1420a0a3e29544e8@mail.gmail.com>
Hello, Marco!
On Thu, 2006-06-22 at 16:04 +0200, Marco Costalba wrote:
> I have pushed some patches that add macros to qgit.
>
> From menu bar it is possible to run a macro created by a fancy new
> dialog invoked by 'Macros->Setup macros...' menu.
I'm not sure they can be called macros. Macro is something consisting
of several commands that are already implemented. So, a macro-assembler
is a program that allows to combine several supported instructions into
one macro. Macros in editors record actions already implemented by the
editors. You may also want to read this:
http://en.wikipedia.org/wiki/Macro
If I understand correctly, qgit doesn't do that. It calls external
commands that are not implemented internally, and it doesn't aggregate
anything. Then why not call them "external commands"?
The interface is quite confusing. I see 5 buttons on top, all of which
are enabled, plus one button labeled as "...", three checkboxes, one
single-line entry and one multiline entry. I have no I idea where to
start. Should I click "new" or white something and then click "new"?
And where's "Cancel"?.
That's what I have tried:
Enter "foo bar" in the multiline entry.
Click "New"
Enter "foobar"
Click "New"
Enter "abc"
Select "foobar"
Now "Run external script" is selected and "foo bar" is gone! I believe
user input should not be discarded without a warning.
I also tried something more meaningful. I create a "pull" macro as an
external script "stg pull". It didn't work. Am I supposed to supply
full path? Does it understand arguments? It the script supposed to be
in a certain format? OK, stg is written in python, but how about
cg-status, a shell script? It doesn't seen to work either.
I could make macros work when I entered the under "Insert commands to
run". The output window looks nice. But I see no indication whether
the script is running or it has finished. I don't see how to terminate
the script "gently", an equivalent of Ctrl-C.
As far as I understand, the text entries should not be enabled at the
same time. But it saw it happening when there were no macros at all.
And if I delete all macros, "Insert commands to run" doesn't work at
all.
What happens to the arguments qgit is asking for if a multiline entry is
executed? I understand they are prepended to the first line. This is
not quite logical. Wouldn't it be better to have a shell like notation
for them?
I see the macros are saved in the qgit configuration for the
user .qt/qgitrc, like this:
[Macro reset]
commands=echo\nstg pull\necho 123\nsleep 5
patch_flags=9040
script_path=/home/proski/bin/cg-reset
Shouldn't only one of commands and script_path be saved? Whouldn't it
be better to save meaningful boolean options instead of the opaque
binary "patch_flags"
And what is "macro_name=New macro" in [General]?
I think I should write you what I would like to see in qgit, but that
would be a separate e-mail.
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: [PATCH] Introduce Git.pm (v3)
From: Petr Baudis @ 2006-06-23 1:12 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1wtghga6.fsf@assigned-by-dhcp.cox.net>
Dear diary, on Fri, Jun 23, 2006 at 02:22:41AM CEST, I got a letter
where Junio C Hamano <junkio@cox.net> said that...
> Petr Baudis <pasky@suse.cz> writes:
>
> >> Eek. It does not compile for me -- maybe there is more
> >> dependencies that need to be listed in INSTALL file?
> >> ...
> >> Git.xs: In function 'XS_Git_xs_hash_object':
> >> Git.xs:27: warning: ISO C90 forbids mixed declarations and code
> >> Git.xs:44: warning: passing argument 1 of 'Perl_io_close' from incompatible pointer type
> >> Git.xs:44: warning: passing argument 2 of 'Perl_io_close' makes pointer from integer without a cast
> >> Git.xs:44: error: too few arguments to function 'Perl_io_close'
> >
> > Oops, sorry. Apparently, I've digged too deep and unleashed a monster of
> > unstable API. Now I've finally discovered perlapio(1) and know I
> > should've just called PerlIO_close(). Below comes a fixed patch, I
> > didn't bother to bump the version number.
>
> Thanks; it compiles now with a few more glitches.
>
> /usr/bin/perl /usr/share/perl/5.8/ExtUtils/xsubpp \
> -typemap /usr/share/perl/5.8/ExtUtils/typemap Git.xs > Git.xsc && \
> mv Git.xsc Git.c
> Please specify prototyping behavior for Git.xs (see perlxs manual)
>
> Says xsubpp.
It's harmless but can be fixed by:
diff --git a/perl/Git.xs b/perl/Git.xs
index 3799ee9..8ab84bb 100644
--- a/perl/Git.xs
+++ b/perl/Git.xs
@@ -17,6 +17,8 @@ #include "ppport.h"
MODULE = Git PACKAGE = Git
+PROTOTYPES: DISABLE
+
# /* TODO: xs_call_gate(). See Git.pm. */
char *
> cc -c -I. -I.. -D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS \
> -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include \
> -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 \
> -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC \
> "-I/usr/lib/perl/5.8/CORE" -Wall
> -Wdeclaration-after-statement \
> -g -DSHA1_HEADER='<openssl/sha.h>' \
> -DGIT_VERSION=\"1.4.1.rc1.g01a1\" Git.c
> Git.xs: In function 'XS_Git_xs__execv_git_cmd':
> Git.xs:57: warning: passing argument 1 of 'free' discards qualifiers from pointer target type
> Git.xs: In function 'XS_Git_xs_hash_object':
> Git.xs:65: warning: ISO C90 forbids mixed declarations and code
>
> I usually compile with -Wdeclaration-after-statement so I
> probably get some more warnings than you saw; it probably is
> primarily xsubpp's fault, but you could work it around by having
> CODE block to be inside an extra set of braces {}.
Sure. Should I resend all the .xs-related patches with the code blocks
in {}, or will you add it at your side?
> Constness reduction of free() is a bit annoying from the point of view of
> the coder who has to cast away constness, so I won't be too
> strict about that, but it would be nicer if we did not have to
> see the warnings.
Sure, it should be trivial to fix.
> rm -f blib/arch/auto/Git/Git.so
> cc -shared -L/usr/local/lib Git.o -o blib/arch/auto/Git/Git.so ../libgit.a \
> -lz -lcrypto \
>
> /usr/bin/ld: ../libgit.a(exec_cmd.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
> ../libgit.a: could not read symbols: Bad value
> collect2: ld returned 1 exit status
> make[1]: *** [blib/arch/auto/Git/Git.so] Error 1
>
> This is a real killer. If we compile everything with -fPIC,
> this goes away, but I do not think we want -fPIC for the core
> level tools. At least not until we are ready to do libgit.so.
Hmm, I didn't get that; I guess that's x86-64 specific. :/ Do you have
any idea what the error actually means? Could the environ be a problem?
(Why aren't we calling just execv()?)
Also, is there any real problem with just using -fPIC?
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.
^ permalink raw reply related
* Re: Tracking CVS
From: Jon Smirl @ 2006-06-23 2:18 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060622135831.GB21864@pasky.or.cz>
On 6/22/06, Petr Baudis <pasky@suse.cz> wrote:
> Dear diary, on Thu, Jun 22, 2006 at 02:41:16PM CEST, I got a letter
> where Jon Smirl <jonsmirl@gmail.com> said that...
> > I'm tracking cvs using this sequence.
> >
> > cvs update
> > cg rm -a
> > cg commit
> > cg add -r .
> > cg commit
> >
> > Is there a way to avoid the two commits? If you do the add with out
> > the intervening commit it just adds the files back.
>
> I think the most straightforward way is:
>
> cvs update
> cg-rm -a
> cg-status -wns \? | xargs cg-add
> cg-commit
This doesn't pick up new directories with recursion.
>
> If you want to be careful about filenames polluted by non-newline
> whitespaces,
>
> cg-status -wns \? | tr '\n' '\0' | xargs -0 cg-add
>
> If you want to be safe even with filenames containing newlines, you need
> to go at the Git level:
>
> git-ls-files -z --others | \
> xargs -0 git-update-index --add --
>
> Perhaps we might make a special command which would sync the index set
> with the working copy set...
>
> --
> Petr "Pasky" Baudis
> Stuff: http://pasky.or.cz/
> A person is just about as big as the things that make them angry.
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: Tracking CVS
From: Jon Smirl @ 2006-06-23 2:24 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <9e4733910606221918r775f49f0l4929f4703281115f@mail.gmail.com>
On 6/22/06, Jon Smirl <jonsmirl@gmail.com> wrote:
> > I think the most straightforward way is:
> >
> > cvs update
> > cg-rm -a
> > cg-status -wns \? | xargs cg-add
> > cg-commit
>
> This doesn't pick up new directories with recursion.
The new directories that came down were empty.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: Tracking CVS
From: Petr Baudis @ 2006-06-23 2:31 UTC (permalink / raw)
To: Jon Smirl; +Cc: git
In-Reply-To: <9e4733910606221918r775f49f0l4929f4703281115f@mail.gmail.com>
Dear diary, on Fri, Jun 23, 2006 at 04:18:32AM CEST, I got a letter
where Jon Smirl <jonsmirl@gmail.com> said that...
> On 6/22/06, Petr Baudis <pasky@suse.cz> wrote:
> > cvs update
> > cg-rm -a
> > cg-status -wns \? | xargs cg-add
> > cg-commit
>
> This doesn't pick up new directories with recursion.
Ah. Either pass -S to cg-status or -r to cg-add.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
A person is just about as big as the things that make them angry.
^ permalink raw reply
* Fixed PPC SHA1
From: linux @ 2006-06-23 0:09 UTC (permalink / raw)
To: git, linuxppc-dev; +Cc: linux
In-Reply-To: <20060619084135.18632.qmail@science.horizon.com>
Okay, here's a tested and working version (the earlier version worked,
too) of a better-scheduled PPC SHA1. This is about 15% faster that the
current sha1ppc.S on a G4, and 5% faster on a G5 when hashing 10 million
bytes, unaligned. (The G5 ratio seems to get better as the sizes fall.)
It's also somewhat smaller, due to using load-multiple instructions.
I have a variant that uses load string (lswi) to load the values to be
hashed that is a few percent faster on a G5, but a few percent slower
on a G4. It's also 52 bytes smaller (out of 4000).
Does anyone have any feeling for the ratio of G4 and G5 machines
out there? I presume for that small a percentage, run-time processor
detection isn't worth it. (Cc: to linuxppc-dev for the experts on
this question.)
I've tried using lmw to load the data, and it's faster if the data is
aligned, but it absolutely dies if the data is not. And due to git's
variable-sized hash prefix, most of git's hashes are of unaligned data.
(No copyright is claimed on the changes to Paul Mackerras' work below.
Enjoy.)
/*
* SHA-1 implementation for PowerPC.
*
* Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
*/
/*
* PowerPC calling convention:
* %r0 - volatile temp
* %r1 - stack pointer.
* %r2 - reserved
* %r3-%r12 - Incoming arguments & return values; volatile.
* %r13-%r31 - Callee-save registers
* %lr - Return address, volatile
* %ctr - volatile
*
* Register usage in this routine:
* %r0 - temp
* %r3 - argument (pointer to 5 words of SHA state)
* %r4 - argument (pointer to data to hash)
* %r5 - Contant K in SHA round (initially number of blocks to hash)
* %r6-%r10 - Working copies of SHA variables A..E (actually E..A order)
* %r11-%r26 - Data being hashed W[].
* %r27-%r31 - Previous copies of A..E, for final add back.
* %ctr - loop count
*/
/*
* We roll the registers for A, B, C, D, E around on each
* iteration; E on iteration t is D on iteration t+1, and so on.
* We use registers 6 - 10 for this. (Registers 27 - 31 hold
* the previous values.)
*/
#define RA(t) (((t)+4)%5+6)
#define RB(t) (((t)+3)%5+6)
#define RC(t) (((t)+2)%5+6)
#define RD(t) (((t)+1)%5+6)
#define RE(t) (((t)+0)%5+6)
/* We use registers 11 - 26 for the W values */
#define W(t) ((t)%16+11)
/* Register 5 is used for the constant k */
/*
* The basic SHA-1 round function is:
* E += ROTL(A,5) + F(B,C,D) + W[i] + K; B = ROTL(B,30)
* Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).
*
* Every 20 rounds, the function F() and the contant K changes:
* - 20 rounds of f0(b,c,d) = "bit wise b ? c : d" = (^b & d) + (b & c)
* - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c
* - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)
* - 20 more rounds of f1(b,c,d)
*
* These are all scheduled for near-optimal performance on a G4.
* The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only
* *consider* starting the oldest 3 instructions per cycle. So to get
* maximum performace out of it, you have to treat it as an in-order
* machine. Which means interleaving the computation round t with the
* computation of W[t+4].
*
* The first 16 rounds use W values loaded directly from memory, while the
* remianing 64 use values computed from those first 16. We preload
* 4 values before starting, so there are three kinds of rounds:
* - The first 12 (all f0) also load the W values from memory.
* - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.
* - The last 4 (all f1) do not do anything with W.
*
* Therefore, we have 6 different round functions:
* STEPD0_LOAD(t,s) - Perform round t and load W(s). s < 16
* STEPD0_UPDATE(t,s) - Perform round t and compute W(s). s >= 16.
* STEPD1_UPDATE(t,s)
* STEPD2_UPDATE(t,s)
* STEPD1(t) - Perform round t with no load or update.
*
* The G5 is more fully out-of-order, and can find the parallelism
* by itself. The big limit is that it has a 2-cycle ALU latency, so
* even though it's 2-way, the code has to be scheduled as if it's
* 4-way, which can be a limit. To help it, we try to schedule the
* read of RA(t) as late as possible so it doesn't stall waiting for
* the previous round's RE(t-1), and we try to rotate RB(t) as early
* as possible while reading RC(t) (= RB(t-1)) as late as possible.
*/
/* the initial loads. */
#define LOADW(s) \
lwz W(s),(s)*4(%r4)
/*
* Perform a step with F0, and load W(s). Uses W(s) as a temporary
* before loading it.
* This is actually 10 instructions, which is an awkward fit.
* It can execute grouped as listed, or delayed one instruction.
* (If delayed two instructions, there is a stall before the start of the
* second line.) Thus, two iterations take 7 cycles, 3.5 cycles per round.
*/
#define STEPD0_LOAD(t,s) \
add RE(t),RE(t),W(t); andc %r0,RD(t),RB(t); and W(s),RC(t),RB(t); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; rotlwi RB(t),RB(t),30; \
add RE(t),RE(t),W(s); add %r0,%r0,%r5; lwz W(s),(s)*4(%r4); \
add RE(t),RE(t),%r0
/*
* This is likewise awkward, 13 instructions. However, it can also
* execute starting with 2 out of 3 possible moduli, so it does 2 rounds
* in 9 cycles, 4.5 cycles/round.
*/
#define STEPD0_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); andc %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0; and %r0,RC(t),RB(t); xor W(s),W(s),W((s)-8); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; xor W(s),W(s),W((s)-14); \
add RE(t),RE(t),%r5; loadk; rotlwi RB(t),RB(t),30; rotlwi W(s),W(s),1; \
add RE(t),RE(t),%r0
/* Nicely optimal. Conveniently, also the most common. */
#define STEPD1_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); xor %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r5; loadk; xor %r0,%r0,RC(t); xor W(s),W(s),W((s)-8); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; xor W(s),W(s),W((s)-14); \
add RE(t),RE(t),%r0; rotlwi RB(t),RB(t),30; rotlwi W(s),W(s),1
/*
* The naked version, no UPDATE, for the last 4 rounds. 3 cycles per.
* We could use W(s) as a temp register, but we don't need it.
*/
#define STEPD1(t) \
add RE(t),RE(t),W(t); xor %r0,RD(t),RB(t); \
rotlwi RB(t),RB(t),30; add RE(t),RE(t),%r5; xor %r0,%r0,RC(t); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; /* spare slot */ \
add RE(t),RE(t),%r0
/*
* 14 instructions, 5 cycles per. The majority function is a bit
* awkward to compute. This can execute with a 1-instruction delay,
* but it causes a 2-instruction delay, which triggers a stall.
*/
#define STEPD2_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); and %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0; xor %r0,RD(t),RB(t); xor W(s),W(s),W((s)-8); \
add RE(t),RE(t),%r5; loadk; and %r0,%r0,RC(t); xor W(s),W(s),W((s)-14); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; rotlwi W(s),W(s),1; \
add RE(t),RE(t),%r0; rotlwi RB(t),RB(t),30
#define STEP0_LOAD4(t,s) \
STEPD0_LOAD(t,s); \
STEPD0_LOAD((t+1),(s)+1); \
STEPD0_LOAD((t)+2,(s)+2); \
STEPD0_LOAD((t)+3,(s)+3)
#define STEPUP4(fn, t, s, loadk...) \
STEP##fn##_UPDATE(t,s,); \
STEP##fn##_UPDATE((t)+1,(s)+1,); \
STEP##fn##_UPDATE((t)+2,(s)+2,); \
STEP##fn##_UPDATE((t)+3,(s)+3,loadk)
#define STEPUP20(fn, t, s, loadk...) \
STEPUP4(fn, t, s,); \
STEPUP4(fn, (t)+4, (s)+4,); \
STEPUP4(fn, (t)+8, (s)+8,); \
STEPUP4(fn, (t)+12, (s)+12,); \
STEPUP4(fn, (t)+16, (s)+16, loadk)
.globl sha1_core
sha1_core:
stwu %r1,-80(%r1)
stmw %r13,4(%r1)
/* Load up A - E */
lmw %r27,0(%r3)
mtctr %r5
1:
LOADW(0)
lis %r5,0x5a82
mr RE(0),%r31
LOADW(1)
mr RD(0),%r30
mr RC(0),%r29
LOADW(2)
ori %r5,%r5,0x7999 /* K0-19 */
mr RB(0),%r28
LOADW(3)
mr RA(0),%r27
STEP0_LOAD4(0, 4)
STEP0_LOAD4(4, 8)
STEP0_LOAD4(8, 12)
STEPUP4(D0, 12, 16,)
STEPUP4(D0, 16, 20, lis %r5,0x6ed9)
ori %r5,%r5,0xeba1 /* K20-39 */
STEPUP20(D1, 20, 24, lis %r5,0x8f1b)
ori %r5,%r5,0xbcdc /* K40-59 */
STEPUP20(D2, 40, 44, lis %r5,0xca62)
ori %r5,%r5,0xc1d6 /* K60-79 */
STEPUP4(D1, 60, 64,)
STEPUP4(D1, 64, 68,)
STEPUP4(D1, 68, 72,)
STEPUP4(D1, 72, 76,)
addi %r4,%r4,64
STEPD1(76)
STEPD1(77)
STEPD1(78)
STEPD1(79)
/* Add results to original values */
add %r31,%r31,RE(0)
add %r30,%r30,RD(0)
add %r29,%r29,RC(0)
add %r28,%r28,RB(0)
add %r27,%r27,RA(0)
bdnz 1b
/* Save final hash, restore registers, and return */
stmw %r27,0(%r3)
lmw %r13,4(%r1)
addi %r1,%r1,80
blr
^ permalink raw reply
* Re: Fixed PPC SHA1
From: linux @ 2006-06-23 0:54 UTC (permalink / raw)
To: git, linuxppc-dev; +Cc: linux
In-Reply-To: <20060623000908.9370.qmail@science.horizon.com>
Here's the lwsi-based version that's slightly faster on a G5, but slightly
slower on a G4.
/*
* SHA-1 implementation for PowerPC.
*
* Copyright (C) 2005 Paul Mackerras <paulus@samba.org>
*/
/*
* PowerPC calling convention:
* %r0 - volatile temp
* %r1 - stack pointer.
* %r2 - reserved
* %r3-%r12 - Incoming arguments & return values; volatile.
* %r13-%r31 - Callee-save registers
* %lr - Return address, volatile
* %ctr - volatile
*
* Register usage in this routine:
* %r0 - temp
* %r3 - argument (pointer to 5 words of SHA state)
* %r4 - argument (pointer to data to hash)
* %r5-%r20 - Data being hashed W[]. (%r5 is initially count of blocks)
* %r21 - Contant K in SHA round
* %r22-%r26 - Working copies of SHA variables A..E (actually E..A order)
* %r27-%r31 - Previous copies of A..E, for final add back.
* %ctr - loop count (copied from %r5 argument)
*
* It's also worth mentioning that PPC assembly accept a bare
* number as a register specifier; the "%r" prefix is actually optional.
* And that number cna be an expression! That simplifies the
* loop unrolling significantly.
*/
/*
* We roll the registers for A, B, C, D, E around on each
* iteration; E on iteration t is D on iteration t+1, and so on.
* We use registers 22 - 26 for this. (Registers 27 - 31 hold
* the previous values.)
*/
#define RA(t) (((t)+4)%5+22)
#define RB(t) (((t)+3)%5+22)
#define RC(t) (((t)+2)%5+22)
#define RD(t) (((t)+1)%5+22)
#define RE(t) (((t)+0)%5+22)
/* Register 21 is used for the constant k */
/* We use registers 5 - 20 for the W values */
#define W(t) ((t)%16+5)
/*
* The basic SHA-1 round function is:
* E += ROTL(A,5) + F(B,C,D) + W[i] + K; B = ROTL(B,30)
* Then the variables are renamed: (A,B,C,D,E) = (E,A,B,C,D).
*
* Every 20 rounds, the function F() and the contant K changes:
* - 20 rounds of f0(b,c,d) = "bit wise b ? c : d" = (^b & d) + (b & c)
* - 20 rounds of f1(b,c,d) = b^c^d = (b^d)^c
* - 20 rounds of f2(b,c,d) = majority(b,c,d) = (b&d) + ((b^d)&c)
* - 20 more rounds of f1(b,c,d)
*
* These are all scheduled for near-optimal performance on a G4.
* The G4 is a 3-issue out-of-order machine with 3 ALUs, but it can only
* *consider* starting the oldest 3 instructions per cycle. So to get
* maximum performace out of it, you have to treat it as an in-order
* machine. Which means interleaving the computation round t with the
* computation of W[t+4].
*
* The first 16 rounds use W values loaded directly from memory, while the
* remianing 64 use values computed from those first 16. We preload
* 4 values before starting, so there are three kinds of rounds:
* - The first 12 (all f0) also load the W values from memory.
* - The next 64 compute W(i+4) in parallel. 8*f0, 20*f1, 20*f2, 16*f1.
* - The last 4 (all f1) do not do anything with W.
*
* Therefore, we have 5 different round functions:
* STEPD0(t,s) - Perform round t
* STEPD0_UPDATE(t,s) - Perform round t and compute W(s). s >= 16.
* STEPD1_UPDATE(t,s)
* STEPD2_UPDATE(t,s)
* STEPD1(t) - Perform round t with no load or update.
*
* There's also provision for inserting an instruction to start loading
* the new K value after it's last used in the given step.
*
* The G5 is more fully out-of-order, and can find the parallelism
* by itself. The big limit is that it has a 2-cycle ALU latency, so
* even though it's 2-way, the code has to be scheduled as if it's
* 4-way, which can be a limit. To help it, we try to schedule the
* read of RA(t) as late as possible so it doesn't stall waiting for
* the previous round's RE(t-1), and we try to rotate RB(t) as early
* as possible while reading RC(t) (= RB(t-1)) as late as possible.
*/
/*
* Okay, we need a naked version of STEPD0. It's 9 instructions.
* Can that be done in 3 cycles, WITHOUT using W(s) as a temp?
* NO. So we need W(s) as a temp. That can be arranged with some
* clever scheduling.
*/
#define STEPD0(t,s) \
/* spare slot */ add RE(t),RE(t),W(t); andc %r0,RD(t),RB(t); \
add RE(t),RE(t),%r0; and W(s),RC(t),RB(t); rotlwi %r0,RA(t),5; \
add RE(t),RE(t),W(s); add %r0,%r0,%r21; rotlwi RB(t),RB(t),30; \
add RE(t),RE(t),%r0;
/*
* This can execute starting with 2 out of 3 possible moduli, so it
* does 2 rounds in 9 cycles, 4.5 cycles/round.
*/
#define STEPD0_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); andc %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0; and %r0,RC(t),RB(t); xor W(s),W(s),W((s)-8); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; xor W(s),W(s),W((s)-14); \
add RE(t),RE(t),%r21; loadk; rotlwi RB(t),RB(t),30; rotlwi W(s),W(s),1; \
add RE(t),RE(t),%r0
/* Nicely optimal. Conveniently, also the most common. */
#define STEPD1_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); xor %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r21; loadk; xor %r0,%r0,RC(t); xor W(s),W(s),W((s)-8); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; xor W(s),W(s),W((s)-14); \
add RE(t),RE(t),%r0; rotlwi RB(t),RB(t),30; rotlwi W(s),W(s),1
/*
* The naked version, no UPDATE, for the last 4 rounds. 3 cycles per.
* We could use W(s) as a temp register, but we don't need it.
*/
#define STEPD1(t) \
add RE(t),RE(t),W(t); xor %r0,RD(t),RB(t); \
add RE(t),RE(t),%r21; xor %r0,%r0,RC(t); rotlwi RB(t),RB(t),30; \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; /* spare slot */ \
add RE(t),RE(t),%r0
/* 5 cycles per */
#define STEPD2_UPDATE(t,s,loadk...) \
add RE(t),RE(t),W(t); and %r0,RD(t),RB(t); xor W(s),W((s)-16),W((s)-3); \
add RE(t),RE(t),%r0; xor %r0,RD(t),RB(t); xor W(s),W(s),W((s)-8); \
add RE(t),RE(t),%r21; loadk; and %r0,%r0,RC(t); xor W(s),W(s),W((s)-14); \
add RE(t),RE(t),%r0; rotlwi %r0,RA(t),5; rotlwi W(s),W(s),1; \
add RE(t),RE(t),%r0; rotlwi RB(t),RB(t),30
#define STEP0_LOAD4(t,s) \
STEPD0_LOAD(t,s); \
STEPD0_LOAD((t+1),(s)+1); \
STEPD0_LOAD((t)+2,(s)+2); \
STEPD0_LOAD((t)+3,(s)+3);
#define STEP0_4(t,s) \
STEPD0(t,s); \
STEPD0((t+1),(s)+1); \
STEPD0((t)+2,(s)+2); \
STEPD0((t)+3,(s)+3);
#define STEP1_4(t) \
STEPD1(t); \
STEPD1((t+1)); \
STEPD1((t)+2); \
STEPD1((t)+3);
#define STEPUP4(fn, t, s, loadk...) \
STEP##fn##_UPDATE(t,s,); \
STEP##fn##_UPDATE((t)+1,(s)+1,); \
STEP##fn##_UPDATE((t)+2,(s)+2,); \
STEP##fn##_UPDATE((t)+3,(s)+3,loadk)
#define STEPUP20(fn, t, s, loadk...) \
STEPUP4(fn, t, s,); \
STEPUP4(fn, (t)+4, (s)+4,); \
STEPUP4(fn, (t)+8, (s)+8,); \
STEPUP4(fn, (t)+12, (s)+12,); \
STEPUP4(fn, (t)+16, (s)+16, loadk)
.globl sha1_core
sha1_core:
stwu %r1,-80(%r1)
stmw %r13,4(%r1)
/* Load up A - E */
lmw %r27,0(%r3)
mtctr %r5
1:
lswi W(0),%r4,32
lis %r21,0x5a82
addi %r4,%r4,32
mr RE(0),%r31
mr RD(0),%r30
mr RC(0),%r29
ori %r21,%r21,0x7999 /* K0-19 */
mr RB(0),%r28
mr RA(0),%r27
STEP0_4(0, 8)
STEP0_4(4, 12)
lswi W(8),%r4,32
STEPUP4(D0, 8, 16,)
STEPUP4(D0, 12, 20,)
STEPUP4(D0, 16, 24, lis %r21,0x6ed9)
ori %r21,%r21,0xeba1 /* K20-39 */
STEPUP20(D1, 20, 28, lis %r21,0x8f1b)
ori %r21,%r21,0xbcdc /* K40-59 */
STEPUP20(D2, 40, 48, lis %r21,0xca62)
ori %r21,%r21,0xc1d6 /* K60-79 */
STEPUP4(D1, 60, 68,)
STEPUP4(D1, 64, 72,)
STEPUP4(D1, 68, 76,)
addi %r4,%r4,32
STEP1_4(72);
STEP1_4(76);
/* Add results to original values */
add %r31,%r31,RE(0)
add %r30,%r30,RD(0)
add %r29,%r29,RC(0)
add %r28,%r28,RB(0)
add %r27,%r27,RA(0)
bdnz 1b
/* Save final hash, restore registers, and return */
stmw %r27,0(%r3)
lmw %r13,4(%r1)
addi %r1,%r1,80
blr
^ permalink raw reply
* Ideas for qgit
From: Pavel Roskin @ 2006-06-23 4:08 UTC (permalink / raw)
To: git, Marco Costalba
Hi, Marco!
As promised, here's what I would like to see in qgit:
1) Bookmarks or quick tags (qtags). It may be useful to mark some
commits to make it easier to navigate qgit. Yet I don't want them to
mix with real tags. Perhaps qgit could save them separately, e.g.
in .git/refs/qtags to facilitate navigation. qtags should appear
separately in the popup menu.
2) The "Patch" tab should be redesigned so that the diff can be shown
against the parent or against head/tag/qtag. Users are not supposed to
enter SHA1. If they have to, then it only confirms that qgit needs
qtags.
3) It would be nice to have some minimal navigating capabilities on the
Patch tab. At least it should be possible to go up and down the
revision list and go to any head/tag/qtag/stgit patch. It would
eliminate the need to switch to the "Rev list" too often.
4) Some bisect support would be nice, at least as good as in gitk.
Actually, I'm not using bisect too much, but it's probably because I'm
not debugging Wine these days. Everything else is intelligible :-)
5) Branch view based on reflog. Probably there should be an interface
allowing to limit the displayed revisions to one branch. I think qgit
should still load all revisions that it loads now, but if users start
complaining about performance too much, maybe qgit should have an option
to load only the logged branch. The problem is that some parents will
be unavailable in the view.
6) Try to unload some stuff from the popup menus to the main menu. It
will be too log if we use it for tags, qtags, branch heads and branch
logs.
7) qgit command line should be documented. "qgit --help" should display
help on stdout.
That said, qgit is in a pretty decent shape right now (except the
"macro" interface, but I'm sure it will be improved before the next
release). I actually used qgit as an important argument for one project
to go with git rather than with Subversion of Mercurial. qgit for
Mercurial would be cool, but I'd leave it to Mercurial fans.
--
Regards,
Pavel Roskin
^ permalink raw reply
* Re: [PATCH] Introduce Git.pm (v3)
From: Junio C Hamano @ 2006-06-23 4:41 UTC (permalink / raw)
To: Petr Baudis; +Cc: git
In-Reply-To: <20060623011205.GJ21864@pasky.or.cz>
Petr Baudis <pasky@suse.cz> writes:
>> cc -shared -L/usr/local/lib Git.o -o blib/arch/auto/Git/Git.so ../libgit.a \
>> -lz -lcrypto \
>>
>> /usr/bin/ld: ../libgit.a(exec_cmd.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
>> ../libgit.a: could not read symbols: Bad value
>> collect2: ld returned 1 exit status
>> make[1]: *** [blib/arch/auto/Git/Git.so] Error 1
>>
>> This is a real killer. If we compile everything with -fPIC,
>> this goes away, but I do not think we want -fPIC for the core
>> level tools. At least not until we are ready to do libgit.so.
>
> Hmm, I didn't get that; I guess that's x86-64 specific. :/
So it seems. Both RH machines I have access at kernel.org and
Debian machines I have locally exhibit that x86-32 is OK and
x86-64 is bad. They all run libc-2.3.6 except RH x86-32 is at
libc-2.3.4.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox