* Re: Performance issue: initial git clone causes massive repack
From: Robin H. Johnson @ 2009-04-05 23:38 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <20090405195714.GA4716@coredump.intra.peff.net>
[-- Attachment #1: Type: text/plain, Size: 4561 bytes --]
On Sun, Apr 05, 2009 at 03:57:14PM -0400, Jeff King wrote:
> > During an initial clone, I see that git-upload-pack invokes
> > pack-objects, despite the ENTIRE repository already being packed - no
> > loose objects whatsoever. git-upload-pack then seems to buffer in
> > memory.
> We need to run pack-objects even if the repo is fully packed because we
> don't know what's _in_ the existing pack (or packs). In particular we
> want to:
> - combine multiple packs into a single pack; this is more efficient on
> the network, because you can find more deltas, and I believe is
> required because the protocol sends only a single pack.
>
> - cull any objects which are not actually part of the reachability
> chain from the refs we are sending
>
> If no work needs to be done for either case, then pack-objects should
> basically just figure that out and then send the existing pack (the
> expensive bit is doing deltas, and we don't consider objects in the same
> pack for deltas, as we know we have already considered that during the
> last repack). It does mmap the whole pack, so you will see your virtual
> memory jump, but nothing should require the whole pack being in memory
> at once.
While my current pack setup has multiple packs of not more than 100MiB
each, that was simply for ease of resume with rsync+http tests. Even
when I already had a single pack, with every object reachable,
pack-objects was redoing the packing.
> pack-objects streams the output to upload-pack, which should only ever
> have an 8K buffer of it in memory at any given time.
>
> At least that is how it is all supposed to work, according to my
> understanding. So if you are seeing very high memory usage, I wonder if
> there is a bug in pack-objects or upload-pack that can be fixed.
>
> Maybe somebody more knowledgeable than me about packing can comment.
Looking at the source, I agree that it should be buffering, however top and ps
seem to disagree. 3GiB VSZ and 2.5GiB RSS here now.
%CPU %MEM VSZ RSS STAT START TIME COMMAND
0.0 0.0 140932 1040 Ss 16:09 0:00 \_ git-upload-pack /code/gentoo/gentoo-git/gentoo-x86.git
32.2 0.0 0 0 Z 16:09 1:50 \_ [git-upload-pack] <defunct>
80.8 44.2 3018484 2545700 Sl 16:09 4:36 \_ git pack-objects --stdout --progress --delta-base-offset
Also, I did another trace, using some other hardware, in a LAN setting, and
noticed that git-upload-pack/pack-objects only seems to start output to the
network after it reaches 100% in 'remote: Compressing objects:'.
Relatedly, throwing more RAM (6GiB total, vs. the previous 2GiB) at the server
in this case cut the 200 wallclock minutes before any sending too place down to
5 minutes.
> > During 'remote: Counting objects: 4886949, done.', git-upload-pack peaks at
> > 2474216KB VSZ and 1143048KB RSS.
> > Shortly thereafter, we get 'remote: Compressing objects: 0%
> > (1328/1994284)', git-pack-objects with ~2.8GB VSZ and ~1.8GB RSS. Here,
> > the CPU burn also starts. On our test server machine (w/ git 1.6.0.6),
> > it takes about 200 minutes walltime to finish the pack, IFF the OOM
> > doesn't kick in.
> Have you tried with a more recent git to see if it is any better? There
> have been a number of changes since 1.6.0.6, although it looks like
> mostly dealing with better recovery from corrupted packs.
Testing right now, the above on the LAN setup was w/ current git HEAD.
> > For the initial clone, can the git-upload-pack algorithm please send
> > existing packs, and only generate a pack containing the non-packed
> > items?
>
> I believe that would require a change to the protocol to allow multiple
> packs. However, it may be possible to munge the pack header in such a
> way that you basically concatenate multiple packs. You would still want
> to peek in the big pack to try deltas from the non-packed items, though.
>
> I think all of this falls into the realm of the GSOC pack caching project.
> There have been other discussions on the list, so you might want to look
> through those for something useful.
Yes, both changing the protocol, and recognizing that existing packs may be
suitable to send could be considered as part of the caching project, as they
fall under the aegis of making good use of what's stored in the cache already
to send.
--
Robin Hugh Johnson
Gentoo Linux Developer & Infra Guy
E-Mail : robbat2@gentoo.org
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85
[-- Attachment #2: Type: application/pgp-signature, Size: 330 bytes --]
^ permalink raw reply
* Re: Performance issue: initial git clone causes massive repack
From: Robin H. Johnson @ 2009-04-05 23:42 UTC (permalink / raw)
To: Git Mailing List
In-Reply-To: <20090405T230552Z@curie.orbis-terrarum.net>
[-- Attachment #1: Type: text/plain, Size: 616 bytes --]
On Sun, Apr 05, 2009 at 04:38:31PM -0700, Robin H. Johnson wrote:
> > Have you tried with a more recent git to see if it is any better? There
> > have been a number of changes since 1.6.0.6, although it looks like
> > mostly dealing with better recovery from corrupted packs.
> Testing right now, the above on the LAN setup was w/ current git HEAD.
Just following up, there seems to be no significant change in results
with v1.6.2.2 over v1.6.0.6.
--
Robin Hugh Johnson
Gentoo Linux Developer & Infra Guy
E-Mail : robbat2@gentoo.org
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85
[-- Attachment #2: Type: application/pgp-signature, Size: 330 bytes --]
^ permalink raw reply
* Re: [RFC/PATCH 0/2] New 'stage' command
From: Johannes Schindelin @ 2009-04-05 23:45 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: markus.heidelberg, Felipe Contreras, git, Junio C Hamano
In-Reply-To: <fabb9a1e0904051622k66352ea4v542ecd99bd5d9c6@mail.gmail.com>
Hi,
On Mon, 6 Apr 2009, Sverre Rabbelier wrote:
> On Mon, Apr 6, 2009 at 01:17, Markus Heidelberg
> <markus.heidelberg@web.de> wrote:
> > Felipe Contreras, 06.04.2009:
> >> But actually, "git diff --cached" is a different action; you can't do
> >> "git diff --cached HEAD^.." for example.
> >
> > And I neither could I do "git stage diff HEAD^.."
>
> I rest my case ;). That's the whole point Felipe is trying to make here.
> $ git diff --cached
> $ git diff HEAD^..
>
> [...]
Could you post at some stage what the current state of this discussion is,
so that people who do not have time to read all those mails, let alone
fire off 10+ mails per hour, can comment about their view of things?
So far, it seems that the view of only a handful is represented in that
thread.
Thanks,
Dscho
^ permalink raw reply
* [PATCH] perl: make Git.pm use new Git::Config module
From: Sam Vilain @ 2009-04-05 23:46 UTC (permalink / raw)
To: git; +Cc: Petr Baudis, Sam Vilain
In-Reply-To: <1238975176-14354-1-git-send-email-sam.vilain@catalyst.net.nz>
Plug these two modules together. The only minor API difference is that
in void context (ie, return value is not being used), the new Git::Config
function does not try to unpack the value. So, the exist test - which was
testing an error condition - must be changed to actually try to retrieve
the values so that the exceptions can happen.
Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
---
perl/Git.pm | 103 +++++++++++++++++++++++++++----------------------------
t/t9700/test.pl | 4 +-
2 files changed, 53 insertions(+), 54 deletions(-)
diff --git a/perl/Git.pm b/perl/Git.pm
index 7d7f2b1..3141b41 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -550,32 +550,38 @@ does. In scalar context requires the variable to be set only one time
(exception is thrown otherwise), in array context returns allows the
variable to be set multiple times and returns all the values.
-This currently wraps command('config') so it is not so fast.
+This delegates via L<Git::Config> for cached config file access. To
+force a re-read of the configuration, call C<$git-E<gt>config->read>
-=cut
+=item config
-sub config {
- my ($self, $var) = _maybe_self(@_);
+With no arguments, the C<config> method returns a L<Git::Config>
+object. See L<Git::Config> for the API information.
- try {
- my @cmd = ('config');
- unshift @cmd, $self if $self;
- if (wantarray) {
- return command(@cmd, '--get-all', $var);
- } else {
- return command_oneline(@cmd, '--get', $var);
- }
- } catch Git::Error::Command with {
- my $E = shift;
- if ($E->value() == 1) {
- # Key not found.
- return;
- } else {
- throw $E;
- }
+=item config ( VARIABLE => value )
+
+With two arguments, the configuration is updated with the passed
+value.
+
+=cut
+
+sub _config {
+ my ($self) = _maybe_self_new(@_);
+ $self->{config} ||= do {
+ require Git::Config;
+ Git::Config->new($self);
};
}
+sub config {
+ (my $self, @_) = _maybe_self_new(@_);
+ if (@_) {
+ return $self->_config->config(@_);
+ }
+ else {
+ return $self->_config;
+ }
+}
=item config_bool ( VARIABLE )
@@ -583,28 +589,21 @@ Retrieve the bool configuration C<VARIABLE>. The return value
is usable as a boolean in perl (and C<undef> if it's not defined,
of course).
-This currently wraps command('config') so it is not so fast.
+This delegates via L<Git::Config> for cached config file access.
+
+=item config_bool ( VARIABLE => value )
+
+Sets a boolean slot to the given value. This always writes 'true' or
+'false' to the configuration file, regardless of the value passed.
=cut
sub config_bool {
- my ($self, $var) = _maybe_self(@_);
+ (my ($self, $var), @_) = _maybe_self_new(@_);
- try {
- my @cmd = ('config', '--bool', '--get', $var);
- unshift @cmd, $self if $self;
- my $val = command_oneline(@cmd);
- return undef unless defined $val;
- return $val eq 'true';
- } catch Git::Error::Command with {
- my $E = shift;
- if ($E->value() == 1) {
- # Key not found.
- return undef;
- } else {
- throw $E;
- }
- };
+ my $conf = $self->_config;
+ $conf->type($var => "boolean");
+ $conf->config($var, @_);
}
=item config_int ( VARIABLE )
@@ -615,26 +614,22 @@ or 'g' in the config file will cause the value to be multiplied
by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
It would return C<undef> if configuration variable is not defined,
-This currently wraps command('config') so it is not so fast.
+This delegates via L<Git::Config> for cached config file access.
+
+=item config_int ( VARIABLE => value )
+
+Sets a integer slot to the given value. This method will reduce the
+written value to the shortest way to express the given number; eg
+1024 is written as C<1k> and 16777216 will be written as C<16M>.
=cut
sub config_int {
- my ($self, $var) = _maybe_self(@_);
+ (my ($self, $var), @_) = _maybe_self_new(@_);
- try {
- my @cmd = ('config', '--int', '--get', $var);
- unshift @cmd, $self if $self;
- return command_oneline(@cmd);
- } catch Git::Error::Command with {
- my $E = shift;
- if ($E->value() == 1) {
- # Key not found.
- return undef;
- } else {
- throw $E;
- }
- };
+ my $conf = $self->_config;
+ $conf->type($var => "integer");
+ $conf->config($var, @_);
}
=item get_colorbool ( NAME )
@@ -1204,6 +1199,7 @@ either version 2, or (at your option) any later version.
=cut
+our $_self;
# Take raw method argument list and return ($obj, @args) in case
# the method was called upon an instance and (undef, @args) if
@@ -1211,6 +1207,9 @@ either version 2, or (at your option) any later version.
sub _maybe_self {
UNIVERSAL::isa($_[0], 'Git') ? @_ : (undef, @_);
}
+sub _maybe_self_new {
+ UNIVERSAL::isa($_[0], 'Git') ? @_ : ($_self||=Git->repository, @_);
+}
# Check if the command id is something reasonable.
sub _check_valid_cmd {
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 697daf3..1b94633 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -35,9 +35,9 @@ is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color");
# Save and restore STDERR; we will probably extract this into a
# "dies_ok" method and possibly move the STDERR handling to Git.pm.
open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR;
-eval { $r->config("test.dupstring") };
+eval { my $x = $r->config("test.dupstring") };
ok($@, "config: duplicate entry in scalar context fails");
-eval { $r->config_bool("test.boolother") };
+eval { my $x = $r->config_bool("test.boolother") };
ok($@, "config_bool: non-boolean values fail");
open STDERR, ">&", $tmpstderr or die "cannot restore STDERR";
--
1.6.0
^ permalink raw reply related
* [PATCH] perl: add new module Git::Config for cached 'git config' access
From: Sam Vilain @ 2009-04-05 23:46 UTC (permalink / raw)
To: git; +Cc: Petr Baudis, Sam Vilain
Add a new module, Git::Config, for a better Git configuration API.
Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
---
perl/Git/Config.pm | 465 ++++++++++++++++++++++++++++++++++++++++++++++++++
perl/Makefile.PL | 5 +-
t/t9700-perl-git.sh | 8 +
t/t9700/TestUtils.pm | 77 +++++++++
t/t9700/config.t | 127 ++++++++++++++
5 files changed, 681 insertions(+), 1 deletions(-)
create mode 100644 perl/Git/Config.pm
create mode 100644 t/t9700/TestUtils.pm
create mode 100644 t/t9700/config.t
diff --git a/perl/Git/Config.pm b/perl/Git/Config.pm
new file mode 100644
index 0000000..a0a6a41
--- /dev/null
+++ b/perl/Git/Config.pm
@@ -0,0 +1,465 @@
+
+package Git::Config;
+
+use 5.006;
+use strict;
+use warnings;
+
+use Git;
+use Error qw(:try);
+
+=head1 NAME
+
+Git::Config - caching interface to git-config state
+
+=head1 SYNOPSIS
+
+ use Git::Config;
+
+ my $conf = Git::Config->new( $git );
+
+ # return single config items
+ my $value = $conf->config( VARIABLE );
+
+ # return multi-config items
+ my @values = $conf->config( VARIABLE );
+
+ # manipulate type of slot, for special interpretation
+ $conf->type( VARIABLE => $type );
+
+ # change value
+ $conf->config( VARIABLE => $value );
+
+ # read or configure a global or system variable
+ $conf->global( VARIABLE => $value );
+ $conf->system( VARIABLE => $value );
+
+ # default is to autoflush
+ $conf->autoflush( 0 );
+
+ # if autoflush is disabled, flush explicitly.
+ $conf->flush;
+
+ # update cache
+ $conf->read;
+
+=head1 DESCRIPTION
+
+This module provides a cached interface to the B<git config> command
+in Perl.
+
+=head1 CONSTRUCTION
+
+=head2 B<Git::Config-E<gt>new( I<$git> )>
+
+Creates a new B<Git::Config> object. Does not read the configuration
+file yet.
+
+=cut
+
+sub new {
+ my $class = shift;
+ my $git = shift || Git->repository;
+ my $self = bless { git => $git }, $class;
+ while ( my ($item, $value) = splice @_, 0, 2 ) {
+ try {
+ $self->$item($value);
+ }
+ catch {
+ throw Error::Simple (
+ "Invalid constructor arg '$item'",
+ );
+ };
+ }
+ return $self;
+}
+
+=head1 METHODS
+
+=head2 B<$conf-E<gt>config( C<item> )>
+
+Reads the value of a particular configuration item.
+When called in B<list context>, returns all values of multiple value
+items.
+When called in B<scalar context>, raises an error if the item is
+specified multiple times.
+
+=head2 B<$conf-E<gt>config( C<item> =E<gt> I<$value> )>
+
+Sets the value of an item.
+If an B<array reference> is specified, the entire list of items is
+replaced with the values specified.
+If a single item is passed but the item is specified multiple times in
+the configuration file, raises an error.
+Returns the old value.
+
+=cut
+
+sub config {
+ return $_[0]->_config("", @_[1..$#_]);
+}
+
+sub _config {
+ my $self = shift;
+ my $which = shift;
+ my $item = shift;
+ my $value_passed = @_;
+ my $value = shift;
+
+ my $type = $self->type( $item );
+
+ my $_which = $which ? "${which}_" : "";
+ my $_read = "read_${_which}state";
+ my $_state = "${_which}state";
+
+ if (!$self->{$_read}) {
+ $self->read($which);
+ }
+
+ my $state;
+ if (exists $self->{$_state}{$item}) {
+ $state = $self->{$_state}{$item};
+ }
+ else {
+ $state = $self->{$_read}{$item};
+ }
+
+ if ($value_passed) {
+ if (!ref $value and defined $value and ref $state) {
+ throw Error::Simple (
+ "'$item' is specified multiple times",
+ );
+ }
+ if ( $type ) {
+ if (ref $value) {
+ $value = [ map { $self->freeze($type, $_) }
+ @$value ];
+ }
+ else {
+ $value = $self->freeze($type, $value);
+ }
+ }
+ $self->{$_state}{$item} = $value;
+ $self->flush() if $self->autoflush;
+ }
+
+ if (defined wantarray) {
+ my @values = ref $state ? @$state :
+ defined $state ? ($state) : ();
+
+ if ( my $type = $self->type( $item ) ) {
+ @values = map { $self->thaw($type, $_) }
+ @values;
+ }
+
+ if ( @values > 1 and
+ ( ($value_passed and not ref $value) or
+ (not $value_passed and not wantarray) )
+ ) {
+ throw Error::Simple (
+ "'$item' is specified multiple times",
+ );
+ }
+
+ return (wantarray ? @values : $values[0]);
+ }
+}
+
+=head2 B<$conf-E<gt>read()>
+
+Reads the current state of the configuration file.
+
+=cut
+
+sub read {
+ my $self = shift;
+ my $which = shift;
+
+ my $git = $self->{git};
+
+ my ($fh, $c) = $git->command_output_pipe(
+ 'config', ( $which ? ("--$which") : () ),
+ '--list',
+ );
+ my $read_state = {};
+
+ while (<$fh>) {
+ my ($item, $value) = m{(.*?)=(.*)};
+ my $sl = \( $read_state->{$item} );
+ if (!defined $$sl) {
+ $$sl = $value;
+ }
+ elsif (!ref $$sl) {
+ $$sl = [ $$sl, $value ];
+ }
+ else {
+ push @{ $$sl }, $value;
+ }
+ }
+
+ $git->command_close_pipe($fh, $c);
+
+ if ( $which ) {
+ $which .= "_";
+ }
+ else {
+ $which = "";
+ };
+
+ $self->{"read_${which}state"} = $read_state;
+}
+
+=head2 type( VARIABLE => $type )
+
+Specifies which set of rules to use when returning to and from the
+config file. C<$type> may be C<string>, C<boolean> or C<integer>.
+Globs such as C<*> are allowed which match everything except C<.>
+(full stop).
+
+=head2 type( VARIABLE )
+
+Returns the first matching defined type rule.
+
+=cut
+
+sub type {
+ my $self = shift;
+ my $item = shift;
+ my $got_type = @_;
+ my $type = shift;
+ $type ||= "string";
+
+ my $types = $self->{types} ||= [];
+ if ( $got_type ) {
+ $item =~ s{([\.(?])}{\\$1}g;
+ $item =~ s{\*}{[^\\.]*}g;
+ $item = qr{^$item$};
+ @$types = grep { $_->[0] ne $item }
+ @$types;
+ push @$types, [ $item, $type ];
+ }
+ else {
+ type:
+ for (@$types) {
+ if ($item =~ m{$_->[0]}) {
+ $type = $_->[1];
+ last type;
+ }
+ }
+
+ $type;
+ }
+}
+
+=head2 global( VARIABLE )
+
+=head2 system( VARIABLE )
+
+Return the value of the given variable in the global or system
+configuration (F<~/.gitconfig> and F</etc/gitconfig> on Unix).
+
+=head2 global( VARIABLE => $value )
+
+=head2 system( VARIABLE => $value )
+
+Set the value of the given variable in the global or system
+configuration.
+
+=cut
+
+sub global { return $_[0]->_config("global", @_[1..$#_]) }
+sub system { return $_[0]->_config("system", @_[1..$#_]) }
+
+=head2 autoflush
+
+Returns 0 or 1 depending on whether autoflush is enabled. Defaults to
+1.
+
+=head2 autoflush ( $value )
+
+Set the value of autoflush. If set to 1, flushes immediately.
+
+=cut
+
+sub autoflush {
+ my $self = shift;
+ if (@_) {
+ $self->{autoflush} = shift;
+ }
+ not (defined $self->{autoflush} and not $self->{autoflush});
+}
+
+=head2 flush
+
+Flushes all changed configuration values to the config file(s).
+
+=cut
+
+sub flush {
+ my $self = shift;
+
+ for my $which ("", "global", "system") {
+ my $st = $which . ($which ? "_" : "") . "state";;
+ my $read = "read_$st";
+ if (my $new = delete $self->{$st}) {
+ $self->_write($which, $new, $self->{$read});
+ $self->read($which);
+ }
+ }
+}
+
+sub _write {
+ my $self = shift;
+ my $which = shift;
+ my $state = shift;
+ my $read_state = shift;
+
+ my $git = $self->{git};
+
+ while (my ($item, $value) = each %$state) {
+ my $old_value = $read_state->{$item};
+ my @cmd = ($which ? ("--$which") : () );
+ my $type = $self->type($item);
+ if ($type ne "string") {
+ push @cmd, "--$type";
+ }
+ if (ref $value) {
+ $git->command_oneline (
+ "config", @cmd, "--replace-all",
+ $item, $value->[0],
+ );
+ for my $i (1..$#$value) {
+ $git->command_oneline (
+ "config", @cmd, "--add",
+ $item, $value->[$i],
+ );
+ };
+ }
+ elsif (defined $value) {
+ $git->command_oneline (
+ "config", @cmd, $item, $value,
+ );
+ }
+ elsif ($read_state->{$item}) {
+ $git->command_oneline (
+ "config", "--unset-all", @cmd,
+ $item, $value,
+ );
+ }
+ else {
+ # nothing to do - already not in config
+ }
+ }
+}
+
+sub _dispatch {
+ no strict 'refs';
+ my $self = shift;
+ my $func = shift;
+ my $type = shift;
+ my $sym = __PACKAGE__."::${type}::$func";
+ defined &{$sym}
+ or throw Error::Simple "Bad type '$type' in $func";
+ &{$sym}(@_, $self);
+}
+
+sub freeze {
+ my $self = shift;
+ $self->_dispatch("freeze", @_);
+}
+
+sub thaw {
+ my $self = shift;
+ $self->_dispatch("thaw", @_);
+}
+
+{
+ package Git::Config::string;
+ sub freeze { shift }
+ sub thaw { shift }
+}
+{
+ package Git::Config::integer;
+ our @mul = ("", "k", "M", "G");
+ sub freeze {
+ my $val = shift;
+ my $scale = 0;
+ while ( (my $num = int($val/1024))*1024 == $val ) {
+ $scale++;
+ $val = $num;
+ last if $scale == $#mul;
+ }
+ $val.$mul[$scale];
+ }
+ our $mul_re = qr/^(\d+)\s*${\( "(".join("|", @mul).")" )}$/i;
+ sub thaw {
+ my $val = shift;
+ $val =~ m{$mul_re}
+ or throw Error::Simple "Bad value for integer: '$val'";
+ my $num = $1;
+ if ($2) {
+ my $scale = 0;
+ do { $num = $num * 1024 }
+ until (lc($mul[++$scale]) eq lc($2));
+ }
+ $num;
+ }
+}
+{
+ package Git::Config::boolean;
+ our @true = qw(true yes 1);
+ our @false = qw(false no 0);
+ our $true_re = qr/^${\( "(".join("|", @true).")" )}$/i;
+ our $false_re = qr/^${\( "(".join("|", @false).")" )}$/i;
+ sub freeze {
+ my $val = shift;
+ if (!!$val) {
+ $true[0];
+ }
+ else {
+ $false[0];
+ }
+ }
+ sub thaw {
+ my $val = shift;
+ if ($val =~ m{$true_re}) {
+ 1;
+ }
+ elsif ($val =~ m{$false_re}) {
+ 0;
+ }
+ else {
+ throw Error::Simple "Bad value for boolean: '$val'";
+ }
+ }
+}
+
+1;
+
+__END__
+
+=head1 SEE ALSO
+
+L<Git>
+
+=head1 AUTHOR AND LICENSE
+
+Copyright 2009, Sam Vilain, L<sam@vilain.net>. All Rights Reserved.
+This program is Free Software; you may use it under the terms of the
+Perl Artistic License 2.0 or later, or the GPL v2 or later.
+
+=cut
+
+# Local Variables:
+# mode: cperl
+# cperl-brace-offset: 0
+# cperl-continued-brace-offset: 0
+# cperl-indent-level: 8
+# cperl-label-offset: -8
+# cperl-merge-trailing-else: nil
+# cperl-continued-statement-offset: 8
+# cperl-indent-parens-as-block: t
+# cperl-indent-wrt-brace: nil
+# End:
+#
+# vim: vim:tw=78:sts=0:noet
diff --git a/perl/Makefile.PL b/perl/Makefile.PL
index 320253e..80df0b0 100644
--- a/perl/Makefile.PL
+++ b/perl/Makefile.PL
@@ -8,7 +8,10 @@ instlibdir:
MAKE_FRAG
}
-my %pm = ('Git.pm' => '$(INST_LIBDIR)/Git.pm');
+my %pm = (map {( "$_.pm" => "\$(INST_LIBDIR)/$_.pm" )}
+ 'Git',
+ 'Git/Config',
+ );
# We come with our own bundled Error.pm. It's not in the set of default
# Perl modules so install it if it's not available on the system yet.
diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh
index b81d5df..2f53d00 100755
--- a/t/t9700-perl-git.sh
+++ b/t/t9700-perl-git.sh
@@ -37,8 +37,16 @@ test_expect_success \
git config --add test.int 2k
'
+export PERL5LIB="$TEST_DIRECTORY/t9700:$GITPERLLIB:$PERL5LIB"
+
test_external_without_stderr \
'Perl API' \
perl "$TEST_DIRECTORY"/t9700/test.pl
+rm -rf .git
+
+test_external_without_stderr \
+ 'config API' \
+ perl "$TEST_DIRECTORY"/t9700/config.t
+
test_done
diff --git a/t/t9700/TestUtils.pm b/t/t9700/TestUtils.pm
new file mode 100644
index 0000000..72a386d
--- /dev/null
+++ b/t/t9700/TestUtils.pm
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+
+package TestUtils;
+
+use Carp;
+use base qw(Exporter);
+BEGIN {
+ our @EXPORT = qw(mk_tmp_repo in_empty_repo tmp_git random_port_pair);
+ $SIG{__WARN__} = sub {
+ my $i = 0;
+ while (my $caller = caller($i)) {
+ if ($caller eq "Test::More") {
+ return 0;
+ }
+ $i++;
+ }
+ my $culprit = caller;
+ if ($culprit =~ m{Class::C3}) {
+ return 1;
+ }
+ else {
+ print STDERR "*** WARNING FROM $culprit FOLLOWS ***\n";
+ }
+ Carp::cluck(@_);
+ print STDERR "*** END OF STACK DUMP ***\n";
+ 1
+ }
+ unless $ENV{NO_WARNING_TRACES};
+}
+
+use Cwd qw(fast_abs_path);
+use File::Temp qw(tempdir);
+
+sub mk_tmp_repo {
+ my $temp_dir = tempdir( "tmpXXXXX", CLEANUP => 1 );
+ system("cd $temp_dir; git-init >/dev/null 2>&1") == 0
+ or die "git-init failed; rc=$?";
+ fast_abs_path($temp_dir);
+}
+
+use Cwd;
+
+sub in_empty_repo {
+ my $coderef = shift;
+ my $old_wd = getcwd;
+ my $path = mk_tmp_repo();
+ chdir($path);
+ $coderef->();
+ chdir($old_wd);
+}
+
+use Git;
+sub tmp_git {
+ Git->repository(mk_tmp_repo);
+}
+
+# return an array ref of two unprivileged ports
+sub random_port_pair {
+ my $port = int(rand(2**16-1024-1)+1024);
+ [ $port, $port + 1 ];
+}
+
+1;
+
+# Local Variables:
+# mode: cperl
+# cperl-brace-offset: 0
+# cperl-continued-brace-offset: 0
+# cperl-indent-level: 8
+# cperl-label-offset: -8
+# cperl-merge-trailing-else: nil
+# cperl-continued-statement-offset: 8
+# cperl-indent-parens-as-block: t
+# cperl-indent-wrt-brace: nil
+# End:
+#
+# vim: vim:tw=78:sts=0:noet
diff --git a/t/t9700/config.t b/t/t9700/config.t
new file mode 100644
index 0000000..395a5c9
--- /dev/null
+++ b/t/t9700/config.t
@@ -0,0 +1,127 @@
+#!/usr/bin/env perl -- -w
+
+use TestUtils;
+use Test::More no_plan;
+use strict;
+
+use Error qw(:try);
+
+use_ok("Git::Config");
+
+in_empty_repo sub {
+ my $git = Git->repository;
+ $git->command_oneline("config", "foo.bar", "baz");
+ $git->command_oneline("config", "list.value", "one");
+ $git->command_oneline("config", "--add", "list.value", "two");
+ $git->command_oneline("config", "foo.intval", "12g");
+ $git->command_oneline("config", "foo.false.val", "false");
+ $git->command_oneline("config", "foo.true.val", "yes");
+
+ my $conf = Git::Config->new();
+ ok($conf, "constructed a new Git::Config");
+ isa_ok($conf, "Git::Config", "Git::Config->new()");
+
+ is($conf->config("foo.bar"), "baz", "read single line");
+ $conf->config("foo.bar", "frop");
+ like($git->command_oneline("config", "foo.bar"), qr/frop/,
+ "->config() has immediate effect");
+ $conf->autoflush(0);
+ is_deeply(
+ [$conf->config("list.value")],
+ [qw(one two)],
+ "read multi-value item",
+ );
+
+ eval {
+ my $val = $conf->config("list.value");
+ };
+ like ($@, qr{multiple}i,
+ "produced an error reading a list into a scalar");
+
+ eval {
+ $conf->config("list.value" => "single");
+ };
+ like($@, qr{multiple}i,
+ "produced an error replacing a list with a scalar");
+
+ ok(eval { $conf->config("foo.bar", [ "baz", "frop"]); 1 },
+ "no error replacing a scalar with a list");
+
+ like($git->command_oneline("config", "foo.bar"), qr/frop/,
+ "->config() no immediate effect with autoflush = 0");
+
+ $conf->flush;
+
+ like($git->command("config", "--get-all", "foo.bar"),
+ qr/baz\s*frop/,
+ "->flush()");
+
+ $conf->config("x.y$$" => undef);
+ my $x = $conf->config("x.y$$");
+ ok(!defined $x, "unset items return undef in scalar context");
+ my @x = $conf->config("x.y$$");
+ ok(@x == 0, "unset items return empty list in list context");
+
+ $conf->config("foo.bar" => undef);
+ @x = $conf->config("foo.bar");
+ ok(@x == 0, "deleted items appear empty immediately");
+ $conf->flush;
+ ok(!eval {
+ $git->command("config", "--get-all", "foo.bar");
+ 1;
+ }, "deleted items are removed from the config file");
+
+ $conf->type("foo.intval", "integer");
+ is($conf->type("foo.intval"), "integer",
+ "->type()");
+ is($conf->config("foo.intval"), 12*1024*1024*1024,
+ "integer thaw");
+ $conf->config("foo.intval", 1025*1024);
+ $conf->type("foo.intval", "string");
+ is($conf->config("foo.intval"), "1025k",
+ "integer freeze");
+
+ $conf->type("foo.*.val", "boolean");
+ is($conf->type("foo.this.val"), "boolean",
+ "wildcard types");
+ is($conf->config("foo.true.val"), 1,
+ "boolean thaw - 'yes'");
+ is($conf->config("foo.false.val"), 0,
+ "boolean thaw - 'false'");
+ my $unset = $conf->config("foo.bar.val");
+ is($unset, undef,
+ "boolean thaw - not present");
+
+ $git->command_oneline("config", "foo.intval", "12g");
+ $git->command_oneline("config", "foo.falseval", "false");
+ $git->command_oneline("config", "foo.trueval", "on");
+
+ SKIP:{
+ if (eval {
+ $git->command(
+ "config", "--global",
+ "--get-all", "foo.bar"
+ );
+ 1;
+ }) {
+ skip "someone set foo.bar in global config", 1;
+ }
+ my @foo_bar = $conf->global("foo.bar");
+ is_deeply(\@foo_bar, [], "->global() reading only");
+ }
+};
+
+
+# Local Variables:
+# mode: cperl
+# cperl-brace-offset: 0
+# cperl-continued-brace-offset: 0
+# cperl-indent-level: 8
+# cperl-label-offset: -8
+# cperl-merge-trailing-else: nil
+# cperl-continued-statement-offset: 8
+# cperl-indent-parens-as-block: t
+# cperl-indent-wrt-brace: nil
+# End:
+#
+# vim: vim:tw=78:sts=0:noet
--
1.6.0
^ permalink raw reply related
* [PATCH] Initial Japanese gitk translation
From: FORS Luis @ 2009-04-06 0:15 UTC (permalink / raw)
To: git
[-- Attachment #1: Type: text/plain, Size: 484 bytes --]
Hello everyone.
My name is Luis Fors. I'm not a great Japanese speaker, and I have almost
zero knowledge of tcl and getttext, but all of my coworkers are Japanese,
and I couldn't just wait around for a translation to appear.
This is my first time contributing, and I have no idea what I'm doing, so be
please be gentle.
This is a patch against gitk.git 5fdcbb13904e6...
Feel free to bang this into whatever shape is necessary to include this in
the next release.
Thank you.
[-- Attachment #2: patch0.patch --]
[-- Type: application/octet-stream, Size: 20776 bytes --]
diff --git a/po/ja.po b/po/ja.po
new file mode 100755
index 0000000..3d81d48
--- /dev/null
+++ b/po/ja.po
@@ -0,0 +1,978 @@
+# Translation of gitk
+# Copyright (C) 2009 Luis Fors
+# This file is distributed under the same license as the gitk package.
+# Luis Fors <l-fors@cerca-jp.com>, 2009.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: gitk\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-10-18 22:03+1100\n"
+"PO-Revision-Date: 2009-04-03 13:22+0900\n"
+"Last-Translator: Luis Fors <l-fors@cerca-jp.com>\n"
+"Language-Team: Japanese\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Japanese\n"
+"X-Poedit-Country: JAPAN\n"
+
+#: gitk:113
+msgid "Couldn't get list of unmerged files:"
+msgstr "未マージファイルのリストをゲット出来ず:"
+
+#: gitk:340
+msgid "No files selected: --merge specified but no files are unmerged."
+msgstr "ファイルが選択されていません:--mergeオプションが指定されたのに未マージファイルはありません。"
+
+#: gitk:343
+msgid "No files selected: --merge specified but no unmerged files are within file limit."
+msgstr "ファイルが選択されていません:--mergeオプションが指定されたのに選択されたファイル未マージファイルを含みません。No hay archivos seleccionados: se seleccionó la opción --merge pero los archivos especificados no necesitan fusión."
+
+#: gitk:378
+msgid "Reading"
+msgstr "読込中"
+
+#: gitk:438
+#: gitk:3462
+msgid "Reading commits..."
+msgstr "コミット読込中…"
+
+#: gitk:441
+#: gitk:1528
+#: gitk:3465
+msgid "No commits selected"
+msgstr "コミットが選択されていません"
+
+#: gitk:1399
+msgid "Can't parse git log output:"
+msgstr "gitログ出力を解析できません:"
+
+#: gitk:1605
+msgid "No commit information available"
+msgstr "コミット情報はありません"
+
+#: gitk:1709
+#: gitk:1731
+#: gitk:3259
+#: gitk:7764
+#: gitk:9293
+#: gitk:9466
+msgid "OK"
+msgstr "OK"
+
+#: gitk:1733
+#: gitk:3260
+#: gitk:7439
+#: gitk:7510
+#: gitk:7613
+#: gitk:7660
+#: gitk:7766
+#: gitk:9294
+#: gitk:9467
+msgid "Cancel"
+msgstr "キャンセル"
+
+#: gitk:1811
+msgid "Update"
+msgstr "更新"
+
+#: gitk:1813
+msgid "Reread references"
+msgstr "照会情報再読込"
+
+#: gitk:1814
+msgid "List references"
+msgstr "照会情報出力"
+
+#: gitk:1815
+msgid "Quit"
+msgstr "終了"
+
+#: gitk:1810
+msgid "File"
+msgstr "ファイル"
+
+#: gitk:1818
+msgid "Preferences"
+msgstr "オプション"
+
+#: gitk:1817
+msgid "Edit"
+msgstr "編集"
+
+#: gitk:1821
+msgid "New view..."
+msgstr "新規ビュー…"
+
+#: gitk:1822
+msgid "Edit view..."
+msgstr "ビューを編集…"
+
+#: gitk:1823
+msgid "Delete view"
+msgstr "ビューを削除"
+
+#: gitk:1825
+msgid "All files"
+msgstr "全ファイル"
+
+#: gitk:1820
+#: gitk:3196
+msgid "View"
+msgstr "ビュー"
+
+#: gitk:1828
+#: gitk:2487
+msgid "About gitk"
+msgstr "gitkについて"
+
+#: gitk:1829
+msgid "Key bindings"
+msgstr "ショートカットキー"
+
+#: gitk:1827
+msgid "Help"
+msgstr "ヘルプ"
+
+#: gitk:1887
+msgid "SHA1 ID: "
+msgstr "SHA1 ID: "
+
+#: gitk:1918
+msgid "Row"
+msgstr "行"
+
+#: gitk:1949
+msgid "Find"
+msgstr "検索"
+
+#: gitk:1950
+msgid "next"
+msgstr "<<"
+
+#: gitk:1951
+msgid "prev"
+msgstr ">>"
+
+#: gitk:1952
+msgid "commit"
+msgstr "コミット"
+
+#: gitk:1955
+#: gitk:1957
+#: gitk:3617
+#: gitk:3640
+#: gitk:3664
+#: gitk:5550
+#: gitk:5621
+msgid "containing:"
+msgstr "含まれている文字列:"
+
+#: gitk:1958
+#: gitk:2954
+#: gitk:2959
+#: gitk:3692
+msgid "touching paths:"
+msgstr "対象パス:"
+
+#: gitk:1959
+#: gitk:3697
+msgid "adding/removing string:"
+msgstr "追加された・削除された文字列:"
+
+#: gitk:1968
+#: gitk:1970
+msgid "Exact"
+msgstr "完全な一致"
+
+#: gitk:1970
+#: gitk:3773
+#: gitk:5518
+msgid "IgnCase"
+msgstr "大小文字を区別せず"
+
+#: gitk:1970
+#: gitk:3666
+#: gitk:3771
+#: gitk:5514
+msgid "Regexp"
+msgstr "正規表現"
+
+#: gitk:1972
+#: gitk:1973
+#: gitk:3792
+#: gitk:3822
+#: gitk:3829
+#: gitk:5641
+#: gitk:5708
+msgid "All fields"
+msgstr "全フィールド"
+
+#: gitk:1973
+#: gitk:3790
+#: gitk:3822
+#: gitk:5580
+msgid "Headline"
+msgstr "見出し"
+
+#: gitk:1974
+#: gitk:3790
+#: gitk:5580
+#: gitk:5708
+#: gitk:6109
+msgid "Comments"
+msgstr "コメント"
+
+#: gitk:1974
+#: gitk:3790
+#: gitk:3794
+#: gitk:3829
+#: gitk:5580
+#: gitk:6045
+#: gitk:7285
+#: gitk:7300
+msgid "Author"
+msgstr "作者"
+
+#: gitk:1974
+#: gitk:3790
+#: gitk:5580
+#: gitk:6047
+msgid "Committer"
+msgstr "コミット者"
+
+#: gitk:2003
+msgid "Search"
+msgstr "検索"
+
+#: gitk:2010
+msgid "Diff"
+msgstr "Diff"
+
+#: gitk:2012
+msgid "Old version"
+msgstr "旧バージョン"
+
+#: gitk:2014
+msgid "New version"
+msgstr "新バージョン"
+
+#: gitk:2016
+msgid "Lines of context"
+msgstr "文脈行数"
+
+#: gitk:2026
+msgid "Ignore space change"
+msgstr "空白を無視"
+
+#: gitk:2084
+msgid "Patch"
+msgstr "パッチ"
+
+#: gitk:2086
+msgid "Tree"
+msgstr "ツリー"
+
+#: gitk:2213
+#: gitk:2226
+msgid "Diff this -> selected"
+msgstr "これ→選択をdiff"
+
+#: gitk:2214
+#: gitk:2227
+msgid "Diff selected -> this"
+msgstr "選択→これをdiff"
+
+#: gitk:2215
+#: gitk:2228
+msgid "Make patch"
+msgstr "パッチを作成"
+
+#: gitk:2216
+#: gitk:7494
+msgid "Create tag"
+msgstr "タグを作成"
+
+#: gitk:2217
+#: gitk:7593
+msgid "Write commit to file"
+msgstr "コミットをファイルに書き込む"
+
+#: gitk:2218
+#: gitk:7647
+msgid "Create new branch"
+msgstr "新しいブランチを作成"
+
+#: gitk:2219
+msgid "Cherry-pick this commit"
+msgstr "このコミットを現在のブランチにあてる(cherry-pick)"
+
+#: gitk:2220
+msgid "Reset HEAD branch to here"
+msgstr "ブランチHEADをここまでリセット"
+
+#: gitk:2234
+msgid "Check out this branch"
+msgstr "このブランチへ切り替える"
+
+#: gitk:2235
+msgid "Remove this branch"
+msgstr "ブランチを削除"
+
+#: gitk:2242
+msgid "Highlight this too"
+msgstr "選択に追加"
+
+#: gitk:2243
+msgid "Highlight this only"
+msgstr "選択する"
+
+#: gitk:2245
+msgid "Blame parent commit"
+msgstr "親コミットを責める"
+
+#: gitk:2488
+msgid ""
+"\n"
+"Gitk - a commit viewer for git\n"
+"\n"
+"Copyright © 2005-2008 Paul Mackerras\n"
+"\n"
+"Use and redistribute under the terms of the GNU General Public License"
+msgstr ""
+"\n"
+"gitk - gitのコミットビューア\n"
+"\n"
+"Copyright © 2005-2008 Paul Mackerras\n"
+"\n"
+"GNU一般公衆利用許諾契約書(GNU GPL)に従って利用・再配布を行ってください。"
+
+#: gitk:2496
+#: gitk:2557
+#: gitk:7943
+msgid "Close"
+msgstr "閉じる"
+
+#: gitk:2515
+msgid "Gitk key bindings"
+msgstr "gitkショートカットキー"
+
+#: gitk:2517
+msgid "Gitk key bindings:"
+msgstr "gitkショートカットキー:"
+
+#: gitk:2519
+#, tcl-format
+msgid "<%s-Q>\t\tQuit"
+msgstr "<%s-Q>\t\t終了"
+
+#: gitk:2520
+msgid "<Home>\t\tMove to first commit"
+msgstr "<Home>\t\t最初のコミットへ移動"
+
+#: gitk:2521
+msgid "<End>\t\tMove to last commit"
+msgstr "<End>\t\t最後のコミットへ移動"
+
+#: gitk:2522
+msgid "<Up>, p, i\tMove up one commit"
+msgstr "<Up>, p, i\t一つ上のコミットへ移動"
+
+#: gitk:2523
+msgid "<Down>, n, k\tMove down one commit"
+msgstr "<Down>, n, k\t一つ下のコミットへ移動"
+
+#: gitk:2524
+msgid "<Left>, z, j\tGo back in history list"
+msgstr "<Left>, z, j\t履歴で後ろへ移動"
+
+#: gitk:2525
+msgid "<Right>, x, l\tGo forward in history list"
+msgstr "<Right>, x, l\t履歴で前へ移動"
+
+#: gitk:2526
+msgid "<PageUp>\tMove up one page in commit list"
+msgstr "<PageUp>\tコミットのリストで一ページ上へ移動"
+
+#: gitk:2527
+msgid "<PageDown>\tMove down one page in commit list"
+msgstr "<PageDown>\tコミットのリストで一ページ下へ移動"
+
+#: gitk:2528
+#, tcl-format
+msgid "<%s-Home>\tScroll to top of commit list"
+msgstr "<%s-Home>\tコミットのリストの冒頭へ移動"
+
+#: gitk:2529
+#, tcl-format
+msgid "<%s-End>\tScroll to bottom of commit list"
+msgstr "<%s-End>\tコミットのリストの末尾へ移動"
+
+#: gitk:2530
+#, tcl-format
+msgid "<%s-Up>\tScroll commit list up one line"
+msgstr "<%s-Up>\tコミットのリストを一行上へスクロール"
+
+#: gitk:2531
+#, tcl-format
+msgid "<%s-Down>\tScroll commit list down one line"
+msgstr "<%s-Down>\tコミットのリストを一行下へスクロール"
+
+#: gitk:2532
+#, tcl-format
+msgid "<%s-PageUp>\tScroll commit list up one page"
+msgstr "<%s-PageUp>\tコミットのリストを一ページ上へスクロール"
+
+#: gitk:2533
+#, tcl-format
+msgid "<%s-PageDown>\tScroll commit list down one page"
+msgstr "<%s-PageDown>\tコミットのリストを一ページ下へスクロール"
+
+#: gitk:2534
+msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
+msgstr "<Shift-Up>\t後進へ検索(うえの新しいリビジョンへ)"
+
+#: gitk:2535
+msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
+msgstr "<Shift-Down>\t前進へ検索(下の古いリビジョンへ)"
+
+#: gitk:2536
+msgid "<Delete>, b\tScroll diff view up one page"
+msgstr "<Delete>, b\tdiffビューを1ページ上へスクロール"
+
+#: gitk:2537
+msgid "<Backspace>\tScroll diff view up one page"
+msgstr "<Backspace>\tdiffビューを1ページ上へスクロール"
+
+#: gitk:2538
+msgid "<Space>\t\tScroll diff view down one page"
+msgstr "<Space>\t\tdiffビューを1ページ下へスクロール"
+
+#: gitk:2539
+msgid "u\t\tScroll diff view up 18 lines"
+msgstr "u\t\tdiffビューを18行上へスクロール"
+
+#: gitk:2540
+msgid "d\t\tScroll diff view down 18 lines"
+msgstr "d\t\tdiffビューを18行下へスクロール"
+
+#: gitk:2541
+#, tcl-format
+msgid "<%s-F>\t\tFind"
+msgstr "<%s-F>\t\t検索"
+
+#: gitk:2542
+#, tcl-format
+msgid "<%s-G>\t\tMove to next find hit"
+msgstr "<%s-G>\t\t次を検索"
+
+#: gitk:2543
+msgid "<Return>\tMove to next find hit"
+msgstr "<Return>\t次を検索"
+
+#: gitk:2544
+msgid "/\t\tMove to next find hit, or redo find"
+msgstr "/\t\t次を検索か検索をやり直す"
+
+#: gitk:2545
+msgid "?\t\tMove to previous find hit"
+msgstr "?\t\t前を検索"
+
+#: gitk:2546
+msgid "f\t\tScroll diff view to next file"
+msgstr "f\t\tdiffビューを次のファイルへスクロール"
+
+#: gitk:2547
+#, tcl-format
+msgid "<%s-S>\t\tSearch for next hit in diff view"
+msgstr "<%s-S>\t\tdiffビューで次を検索"
+
+#: gitk:2548
+#, tcl-format
+msgid "<%s-R>\t\tSearch for previous hit in diff view"
+msgstr "<%s-R>\t\tdiffビューで前を検索"
+
+#: gitk:2549
+#, tcl-format
+msgid "<%s-KP+>\tIncrease font size"
+msgstr "<%s-KP+>\tテキストサイズを大きく"
+
+#: gitk:2550
+#, tcl-format
+msgid "<%s-plus>\tIncrease font size"
+msgstr "<%s-プラス>\tテキストサイズを大きく"
+
+#: gitk:2551
+#, tcl-format
+msgid "<%s-KP->\tDecrease font size"
+msgstr "<%s-KP->\tテキストサイズを小さく"
+
+#: gitk:2552
+#, tcl-format
+msgid "<%s-minus>\tDecrease font size"
+msgstr "<%s-マイナス>\tテキストサイズを小さく"
+
+#: gitk:2553
+msgid "<F5>\t\tUpdate"
+msgstr "<F5>\t\t更新"
+
+#: gitk:3200
+msgid "Gitk view definition"
+msgstr "gitkビュー定義"
+
+#: gitk:3225
+msgid "Name"
+msgstr "名前"
+
+#: gitk:3228
+msgid "Remember this view"
+msgstr "ビューを記憶する"
+
+#: gitk:3232
+msgid "Commits to include (arguments to git log):"
+msgstr "対象コミット(git logへの引数):"
+
+#: gitk:3239
+msgid "Command to generate more commits to include:"
+msgstr "対象コミットを生成する命令:"
+
+#: gitk:3246
+msgid "Enter files and directories to include, one per line:"
+msgstr "一行ずつ、対象ファイル名とディレクトリ名を入力してください:"
+
+#: gitk:3293
+msgid "Error in commit selection arguments:"
+msgstr "コミット選択引数エラー:"
+
+#: gitk:3347
+#: gitk:3399
+#: gitk:3842
+#: gitk:3856
+#: gitk:5060
+#: gitk:10141
+#: gitk:10142
+msgid "None"
+msgstr "無し"
+
+#: gitk:3790
+#: gitk:5580
+#: gitk:7287
+#: gitk:7302
+msgid "Date"
+msgstr "日付"
+
+#: gitk:3790
+#: gitk:5580
+msgid "CDate"
+msgstr "作成日付"
+
+#: gitk:3939
+#: gitk:3944
+msgid "Descendant"
+msgstr "子孫"
+
+#: gitk:3940
+msgid "Not descendant"
+msgstr "非子孫"
+
+#: gitk:3947
+#: gitk:3952
+msgid "Ancestor"
+msgstr "祖先"
+
+#: gitk:3948
+msgid "Not ancestor"
+msgstr "非祖先"
+
+#: gitk:4187
+msgid "Local changes checked in to index but not committed"
+msgstr "インデックスに入っている未コミット変更"
+
+#: gitk:4220
+msgid "Local uncommitted changes, not checked in to index"
+msgstr "インデックスの入っていない未コミット変更"
+
+#: gitk:5549
+msgid "Searching"
+msgstr "検索中"
+
+#: gitk:6049
+msgid "Tags:"
+msgstr "タグ:"
+
+#: gitk:6066
+#: gitk:6072
+#: gitk:7280
+msgid "Parent"
+msgstr "親"
+
+#: gitk:6077
+msgid "Child"
+msgstr "子"
+
+#: gitk:6086
+msgid "Branch"
+msgstr "ブランチ"
+
+#: gitk:6089
+msgid "Follows"
+msgstr "次コミット"
+
+#: gitk:6092
+msgid "Precedes"
+msgstr "前コミット"
+
+#: gitk:6378
+msgid "Error getting merge diffs:"
+msgstr "マージdiff読込エラー:"
+
+#: gitk:7113
+msgid "Goto:"
+msgstr "Goto:"
+
+#: gitk:7115
+msgid "SHA1 ID:"
+msgstr "SHA1 ID:"
+
+#: gitk:7134
+#, tcl-format
+msgid "Short SHA1 id %s is ambiguous"
+msgstr "%sを含むSHA1が複数存在する"
+
+#: gitk:7146
+#, tcl-format
+msgid "SHA1 id %s is not known"
+msgstr "SHA1の%sは不明"
+
+#: gitk:7148
+#, tcl-format
+msgid "Tag/Head %s is not known"
+msgstr "タグ・ブランチ%s不明"
+
+#: gitk:7290
+msgid "Children"
+msgstr "子"
+
+#: gitk:7347
+#, tcl-format
+msgid "Reset %s branch to here"
+msgstr "ブランチ%sをここまでリセット"
+
+#: gitk:7349
+msgid "Detached head: can't reset"
+msgstr "頭コミットが分離:リセット不可能"
+
+#: gitk:7381
+msgid "Top"
+msgstr "Top"
+
+#: gitk:7382
+msgid "From"
+msgstr "From"
+
+#: gitk:7387
+msgid "To"
+msgstr "To"
+
+#: gitk:7410
+msgid "Generate patch"
+msgstr "パッチ生成"
+
+#: gitk:7412
+msgid "From:"
+msgstr "From:"
+
+#: gitk:7421
+msgid "To:"
+msgstr "To:"
+
+#: gitk:7430
+msgid "Reverse"
+msgstr "後進"
+
+#: gitk:7432
+#: gitk:7607
+msgid "Output file:"
+msgstr "出力ファイル:"
+
+#: gitk:7438
+msgid "Generate"
+msgstr "生成"
+
+#: gitk:7474
+msgid "Error creating patch:"
+msgstr "パッチ作成エラー:"
+
+#: gitk:7496
+#: gitk:7595
+#: gitk:7649
+msgid "ID:"
+msgstr "ID:"
+
+#: gitk:7505
+msgid "Tag name:"
+msgstr "タグ名:"
+
+#: gitk:7509
+#: gitk:7659
+msgid "Create"
+msgstr "作成"
+
+#: gitk:7524
+msgid "No tag name specified"
+msgstr "タグ名未指定"
+
+#: gitk:7528
+#, tcl-format
+msgid "Tag \"%s\" already exists"
+msgstr "タグ\"%s\"が既に存在する"
+
+#: gitk:7534
+msgid "Error creating tag:"
+msgstr "タグ作成エラー:"
+
+#: gitk:7604
+msgid "Command:"
+msgstr "命令:"
+
+#: gitk:7612
+msgid "Write"
+msgstr "書き込み"
+
+#: gitk:7628
+msgid "Error writing commit:"
+msgstr "コミット書き込みエラー:"
+
+#: gitk:7654
+msgid "Name:"
+msgstr "名前:"
+
+#: gitk:7674
+msgid "Please specify a name for the new branch"
+msgstr "新しいブランチ名を定義してください"
+
+#: gitk:7703
+#, tcl-format
+msgid "Commit %s is already included in branch %s -- really re-apply it?"
+msgstr "リビジョン%sはブランチ%sに既に存在します。それでもあてますか?"
+
+#: gitk:7708
+msgid "Cherry-picking"
+msgstr "リビジョンを任意に当てはまる(cherry-picking)"
+
+#: gitk:7720
+msgid "No changes committed"
+msgstr "コミットされた変更はありません"
+
+#: gitk:7745
+msgid "Confirm reset"
+msgstr "リセットを確認"
+
+#: gitk:7747
+#, tcl-format
+msgid "Reset branch %s to %s?"
+msgstr "ブランチ%sを%sまでリセット?"
+
+#: gitk:7751
+msgid "Reset type:"
+msgstr "リセット種別:"
+
+#: gitk:7755
+msgid "Soft: Leave working tree and index untouched"
+msgstr "軟らかい:ブランチもインデックスもそのまま"
+
+#: gitk:7758
+msgid "Mixed: Leave working tree untouched, reset index"
+msgstr "中庸:ブランチを触れずにインデックスをリセット"
+
+#: gitk:7761
+msgid ""
+"Hard: Reset working tree and index\n"
+"(discard ALL local changes)"
+msgstr ""
+"硬い:ブランチとインデックスをリセット\n"
+"(ローカル変更が全て破壊される!)"
+
+#: gitk:7777
+msgid "Resetting"
+msgstr "リセット中"
+
+#: gitk:7834
+msgid "Checking out"
+msgstr "切り替え中"
+
+#: gitk:7885
+msgid "Cannot delete the currently checked-out branch"
+msgstr "現在使用中のブランチを削除することはできません"
+
+#: gitk:7891
+#, tcl-format
+msgid "The commits on branch %s aren't on any other branch.\nReally delete branch %s?"
+msgstr "ブランチ%sが一意リビジョンを含む。\nそれでも削除しますか?"
+
+#: gitk:7922
+#, tcl-format
+msgid "Tags and heads: %s"
+msgstr "タグとブランチ:%s"
+
+#: gitk:7936
+msgid "Filter"
+msgstr "フィルタ"
+
+#: gitk:8230
+msgid "Error reading commit topology information; branch and preceding/following tag information will be incomplete."
+msgstr "トポロジー情報読込エラー:ブランチデータと前・次タグデータが不完全になります。"
+
+#: gitk:9216
+msgid "Tag"
+msgstr "タグ"
+
+#: gitk:9216
+msgid "Id"
+msgstr "Id"
+
+#: gitk:9262
+msgid "Gitk font chooser"
+msgstr "gitkフォント選択"
+
+#: gitk:9279
+msgid "B"
+msgstr "B"
+
+#: gitk:9282
+msgid "I"
+msgstr "I"
+
+#: gitk:9375
+msgid "Gitk preferences"
+msgstr "gitkオプション"
+
+#: gitk:9376
+msgid "Commit list display options"
+msgstr "コミットリスト表示設定"
+
+#: gitk:9379
+msgid "Maximum graph width (lines)"
+msgstr "グラフ幅上限(ライン数)"
+
+#: gitk:9383
+msgid "Maximum graph width (% of pane)"
+msgstr "グラフ幅上限(パネルの何%)"
+
+#: gitk:9388
+msgid "Show local changes"
+msgstr "ローカル変更を教示"
+
+#: gitk:9393
+msgid "Auto-select SHA1"
+msgstr "SHA1を自動で選択"
+
+#: gitk:9398
+msgid "Diff display options"
+msgstr "diff表示設定"
+
+#: gitk:9400
+msgid "Tab spacing"
+msgstr "タブの文字数"
+
+#: gitk:9404
+msgid "Display nearby tags"
+msgstr "隣接タグを表示"
+
+#: gitk:9409
+msgid "Limit diffs to listed paths"
+msgstr "diffを表示されているパスに限る"
+
+#: gitk:9414
+msgid "Support per-file encodings"
+msgstr "ファイル毎に文字コード対応"
+
+#: gitk:9421
+msgid "External diff tool"
+msgstr "外部diffツール"
+
+#: gitk:9423
+msgid "Choose..."
+msgstr "選択…"
+
+#: gitk:9428
+msgid "Colors: press to choose"
+msgstr "色選択:押してください"
+
+#: gitk:9431
+msgid "Background"
+msgstr "背景"
+
+#: gitk:9435
+msgid "Foreground"
+msgstr "文字"
+
+#: gitk:9439
+msgid "Diff: old lines"
+msgstr "diff:旧行"
+
+#: gitk:9444
+msgid "Diff: new lines"
+msgstr "diff:新行"
+
+#: gitk:9449
+msgid "Diff: hunk header"
+msgstr "diff:塊のヘッダー"
+
+#: gitk:9455
+msgid "Select bg"
+msgstr "選択の背景色"
+
+#: gitk:9459
+msgid "Fonts: press to choose"
+msgstr "フォント選択:押してください"
+
+#: gitk:9461
+msgid "Main font"
+msgstr "主フォント"
+
+#: gitk:9462
+msgid "Diff display font"
+msgstr "diff表示フォント"
+
+#: gitk:9463
+msgid "User interface font"
+msgstr "UIフォント"
+
+#: gitk:9488
+#, tcl-format
+msgid "Gitk: choose color for %s"
+msgstr "gitk:%sの色を選択"
+
+#: gitk:9934
+msgid ""
+"Sorry, gitk cannot run with this version of Tcl/Tk.\n"
+" Gitk requires at least Tcl/Tk 8.4."
+msgstr ""
+"gitkは現在のTcl/Tkバージョンでは実行できません。\n"
+"Tcl/Tkバージョン8.4はgitkの最低条件です。"
+
+#: gitk:10047
+msgid "Cannot find a git repository here."
+msgstr "gitリポジトリはここにありません。"
+
+#: gitk:10051
+#, tcl-format
+msgid "Cannot find the git directory \"%s\"."
+msgstr "gitディレクトリー \"%s\"が見つかりません。"
+
+#: gitk:10098
+#, tcl-format
+msgid "Ambiguous argument '%s': both revision and filename"
+msgstr "多義引数'%s':リビジョンでもファイル名でもあります"
+
+#: gitk:10110
+msgid "Bad arguments to gitk:"
+msgstr "gitkの引数に誤り:"
+
+#: gitk:10170
+msgid "Command line"
+msgstr "コマンドライン"
+
^ permalink raw reply related
* Re: Re: Performance issue: initial git clone causes massive repack
From: Robin H. Johnson @ 2009-04-06 0:29 UTC (permalink / raw)
To: Git List
In-Reply-To: <0015174c150e49b5740466d7d2c2@google.com>
[-- Attachment #1: Type: text/plain, Size: 1503 bytes --]
On Mon, Apr 06, 2009 at 12:17:18AM +0000, SRabbelier@gmail.com wrote:
> Heya,
>
> On Mon, Apr 6, 2009 at 01:38, Robin H. Johnson robbat2@gentoo.org> wrote:
>> Relatedly, throwing more RAM (6GiB total, vs. the previous 2GiB) at the
>> server
>> in this case cut the 200 wallclock minutes before any sending too place
>> down to
>> 5 minutes.
> I'm curious what kind of hardware changes you made to achieve such an
> enormous effect? Was it just added RAM on the same machine?
No, see the paragraph previous to that, showing it was a different machine that
just happened to have 6GiB of RAM.
The key difference is that having 6GiB of RAM was enough to stop the
swap/OOM-killing of git-pack-objects/git-upload-pack that happened on the slow
server, which I considered to be entirely unwarranted since the pack was
already generated and perfect for use.
"Slow" server:
- deadline scheduler
- AMD Opteron 1210, single socket, 2 cores @ 1.8GHZ
- 2GB Reg ECC RAM
- 2x ST3250620AS, RAID1
- 100Mbit internet feed, co-located in Texas.
"Fast" server:
- deadline scheduler
- Intel Core2 Q6600, single socket, 4 cores @ 2.4GHz
- ~5.7GiB of cheap RAM (6GiB in the box, 256 not usable due to BIOS MTRR brokeness)
- 7x ST3320620AS, RAID-5.
- Sitting on my home LAN, with a very crappy upload bandwidth to the Internet.
--
Robin Hugh Johnson
Gentoo Linux Developer & Infra Guy
E-Mail : robbat2@gentoo.org
GnuPG FP : 11AC BA4F 4778 E3F6 E4ED F38E B27B 944E 3488 4E85
[-- Attachment #2: Type: application/pgp-signature, Size: 330 bytes --]
^ permalink raw reply
* Re: Gnus content transfer encoding
From: Junio C Hamano @ 2009-04-06 0:30 UTC (permalink / raw)
To: Teemu Likonen
Cc: Reece Dunn, Felipe Contreras, Sverre Rabbelier, Christian Couder,
git, Johannes Schindelin
In-Reply-To: <87r60626c9.fsf_-_@iki.fi>
Teemu Likonen <tlikonen@iki.fi> writes:
> On 2009-04-05 13:02 (-0700), Junio C Hamano wrote:
>
>> Reece Dunn <msclrhd@googlemail.com> writes:
>>> I think Junio is trying to learn base64 :)!
>>
>> I think that is what my Gnus/message-mode did. I do not know which
>> letter triggered it to decide it is UTF-8 to begin with, though. As
>> far as I am aware, I didn't type anything non-ascii in my message.
>
> You can customize the encoding decision mechanism, for example:
>
> (setq mm-body-charset-encoding-alist
> '((iso-8859-1 . 8bit)
> (utf-8 . 8bit)))
>
> For more info, see:
>
> C-h v mm-body-charset-encoding-alist RET
Interesting.
I have had these for a long time:
(setq mm-coding-system-priorities '(us-ascii iso-2022-jp utf-8 iso-8859-1))
(setq mm-content-transfer-encoding-defaults
'(("text/.*" 8bit)
("message/rfc822" 8bit)
("application/emacs-lisp" qp-or-base64)
("application/x-emacs-lisp" qp-or-base64)
("application/x-patch" qp-or-base64)
(".*" base64)))
I did not have any customization on my own to body-charset-encoding-alist
and C-h v gave me:
mm-body-charset-encoding-alist's value is
((iso-2022-jp . 7bit)
(iso-2022-jp-2 . 7bit)
(utf-16 . base64)
(utf-16be . base64)
(utf-16le . base64))
I'll have the following in my .emacs in addition to the coding-system-prio
and c-t-e-defaults I already have:
(setq mm-body-charset-encoding-alist
'((iso-2022-jp . 7bit)
(iso-2022-jp-2 . 7bit)
(iso-8859-1 . 8bit)
(utf-8 . 8bit)))
and will see what happens, but I wonder how this new one interacts with
the c-t-e-defaults.
Thanks.
^ permalink raw reply
* Re: git-{diff,merge} refactor round 2
From: Junio C Hamano @ 2009-04-06 0:33 UTC (permalink / raw)
To: markus.heidelberg
Cc: David Aguilar, Johannes.Schindelin, charles, git, msysgit
In-Reply-To: <200904060015.17145.markus.heidelberg@web.de>
Markus Heidelberg <markus.heidelberg@web.de> writes:
> David Aguilar, 05.04.2009:
> ...
>> 1. Base it on the current master, completely throwing away
>> the existing da/difftool branch. That would include throwing
>> away the commit that's in next if we really want to be clean
>> about the history. In the process, move Markus' mergetool
>> fixes for windows to the top so that they can be applied
>> independently if necessary. This series would then depend
>> on them.
>
> This is my favourite, too.
Ok. You two forgot another obvious option of not doing anything, but
since both of you seem to be Ok with the rewrite, let's take that
approach. It is easy to revert the one premature merge out of next and
then merge the cleaned-up version.
> Yes, some squashing would be nice. Similar commit messages are confusing
> when reading the history.
Agreed.
^ permalink raw reply
* Re: Running 'git pull' from an unnamed branch
From: Junio C Hamano @ 2009-04-06 1:05 UTC (permalink / raw)
To: Reece Dunn; +Cc: Git List
In-Reply-To: <3f4fd2640904051433u199587c3wc9bf080d138944e7@mail.gmail.com>
Reece Dunn <msclrhd@googlemail.com> writes:
> diff --git a/git-pull.sh b/git-pull.sh
> index 8a26763..00a72dd 100755
> --- a/git-pull.sh
> +++ b/git-pull.sh
> @@ -97,6 +97,10 @@ error_on_no_merge_candidates () {
> echo "try again (e.g. 'git pull <repository> <refspec>')."
> echo "See git-pull(1) for details on the refspec."
> echo
> + echo "You may not be on a branch. In this case, you need to move"
> + echo "onto the branch you want to pull to (usually master):"
> + echo " git checkout <branch>"
> + echo
I do not think that is necessarily what the user wanted to hear. Often I
create trial merges on a detached HEAD when I hear a pull-request from
others (I have a few work trees that share the repository with my primary
working area, made with contrib/workdir/git-new-workdir script, and their
HEAD are typically detached at the tip of the master), and in such a use
case, the first line of the instruction in the context in your patch is
the right thing to give. I do not want to have the resulting trial merge
anywhere on my real branches, and do not want to be told to switch to any
of them.
We really should teach people, especially the new ones early on, that "git
push" and "git pull" are meant to be told where-to/from and what, and how
to drive these commands with explicit arguments, before letting them rely
on the default configuration blindly without understanding the underlying
concepts.
The automation given by the configuration variables is certainly nice, and
the default created by "clone", "remote add" and "checkout -b" (with its
implicit "track") may make them simpler to operate for every day life, but
there is a limit. Working on a detached HEAD is an ultimate free-form
hacking, and you do not even necessarily _want_ to have a "while my HEAD
is detached, please always do this" default configured.
^ permalink raw reply
* Re: [PATCH] Initial Japanese gitk translation
From: Junio C Hamano @ 2009-04-06 1:40 UTC (permalink / raw)
To: FORS Luis; +Cc: git
In-Reply-To: <FD6CAD0757FA434C91E904C1F202CBA1@DELL300>
"FORS Luis" <l-fors@cerca-jp.com> writes:
"FORS Luis" <l-fors@cerca-jp.com> writes:
> My name is Luis Fors. I'm not a great Japanese speaker, and I have
> almost zero knowledge of tcl and getttext, but all of my coworkers are
> Japanese, and I couldn't just wait around for a translation to appear.
>
> This is my first time contributing, and I have no idea what I'm doing,
> so be please be gentle.
>
> This is a patch against gitk.git 5fdcbb13904e6...
>
> Feel free to bang this into whatever shape is necessary to include
> this in the next release.
>
> Thank you.
Judged by a native speaker (that is me), there are some funny translations
we may want to fix up, but it should serve as a good basis for anybody to
whip it into shape good enough and forward it to Paul to be merged.
Thanks.
> +#: gitk:113
> +msgid "Couldn't get list of unmerged files:"
> +msgstr "未マージファイルのリストをゲット出来ず:"
You are using です・ます style throughout the translation, so you would
want to say:
未マージファイルのリストを取得できません
or something like that.
> +#: gitk:340
> +msgid "No files selected: --merge specified but no files are unmerged."
> +msgstr "ファイルが選択されていません:--mergeオプションが指定されたのに未マージファイルはありません。"
> +
> +#: gitk:343
> +msgid "No files selected: --merge specified but no unmerged files are within file limit."
> +msgstr "ファイルが選択されていません:--mergeオプションが指定されたのに選択されたファイル未マージファイルを含みません。No hay archivos seleccionados: se seleccionó la opción --merge pero los archivos especificados no necesitan fusión."
No habla Español, perdóname.
> +#: gitk:1813
> +msgid "Reread references"
> +msgstr "照会情報再読込"
> +
> +#: gitk:1814
> +msgid "List references"
> +msgstr "照会情報出力"
I have never seen ref and reference translated as 照会 in the context of
git.
There are some people working on translating the documentation; a good
starting point would be:
http://www8.atwiki.jp/git_jp/
and the glossary's translation is here.
http://github.com/yasuaki/git-manual-jp/blob?path[]=Documentation&path[]=glossary.txt&raw=true
They translate "ref" as 参照 which may not be best but looks better than
照会. I wrote a magazine article in Japanese and I ended up calling them
just リファレンス --- write pronunciation in kana which is a universal
cop-out X-<.
> +msgid "Exact"
> +msgstr "完全な一致"
I'd drop な if I were translating this
> +#: gitk:1970
> +#: gitk:3773
> +#: gitk:5518
> +msgid "IgnCase"
> +msgstr "大小文字を区別せず"
I'd say 区別しない instead of 区別せず as the rest is in です・ます
style.
> +msgid "Author"
> +msgstr "作者"
> +
> +msgid "Committer"
> +msgstr "コミット者"
I used 著者 for Author and 記録者 for Committer. The translated glossary
I mentioned earlier seems to agree with me on Author (it cops out on
committer by saying "コミットした人").
> +msgid "Diff this -> selected"
> +msgstr "これ→選択をdiff"
> +msgid "Diff selected -> this"
> +msgstr "選択→これをdiff"
Perhaps
「これと選択したコミットの差分を見る」
「選択したコミットとこれの差分を見る」
If you can affored to go a bit longer, I'd say このコミット instead of こ
れ here, though.
> +#: gitk:2245
> +msgid "Blame parent commit"
> +msgstr "親コミットを責める"
This is a hard one ;-)
> +msgstr "<%s-Down>\tコミットのリストを一行下へスクロール"
> +
> +#: gitk:2532
> +#, tcl-format
> +msgid "<%s-PageUp>\tScroll commit list up one page"
> +msgstr "<%s-PageUp>\tコミットのリストを一ページ上へスクロール"
> +
> +#: gitk:2533
> +#, tcl-format
> +msgid "<%s-PageDown>\tScroll commit list down one page"
> +msgstr "<%s-PageDown>\tコミットのリストを一ページ下へスクロール"
> +
> +#: gitk:2534
> +msgid "<Shift-Up>\tFind backwards (upwards, later commits)"
> +msgstr "<Shift-Up>\t後進へ検索(うえの新しいリビジョンへ)"
逆方向検索 うえ should be 上
> +#: gitk:2535
> +msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)"
> +msgstr "<Shift-Down>\t前進へ検索(下の古いリビジョンへ)"
前方向検索
> +msgid "Local changes checked in to index but not committed"
> +msgstr "インデックスに入っている未コミット変更"
> +
> +#: gitk:4220
> +msgid "Local uncommitted changes, not checked in to index"
> +msgstr "インデックスの入っていない未コミット変更"
「に」入っていない。not「の」
> +msgid "Short SHA1 id %s is ambiguous"
> +msgstr "%sを含むSHA1が複数存在する"
Good job!!
> +#: gitk:7146
> +#, tcl-format
> +msgid "SHA1 id %s is not known"
> +msgstr "SHA1の%sは不明"
You probably do not want の here.
> +#: gitk:7430
> +msgid "Reverse"
> +msgstr "後進"
I am not sure about the context of this message but shouldn't it be 後退?
> +msgid "Tag \"%s\" already exists"
> +msgstr "タグ\"%s\"が既に存在する"
・・・は既に存在します
> +#: gitk:7708
> +msgid "Cherry-picking"
> +msgstr "リビジョンを任意に当てはまる(cherry-picking)"
当ては「め」る, perhaps?
> +#: gitk:7755
> +msgid "Soft: Leave working tree and index untouched"
> +msgstr "軟らかい:ブランチもインデックスもそのまま"
> +
> +#: gitk:7758
> +msgid "Mixed: Leave working tree untouched, reset index"
> +msgstr "中庸:ブランチを触れずにインデックスをリセット"
> +#: gitk:7761
> +msgid ""
> +"Hard: Reset working tree and index\n"
> +"(discard ALL local changes)"
> +msgstr ""
> +"硬い:ブランチとインデックスをリセット\n"
> +"(ローカル変更が全て破壊される!)"
These are hard ones. I'd leave Soft/Mixed/Hard labels in
English/alphabets if I were doing this, though.
> +msgid "The commits on branch %s aren't on any other branch.\nReally delete branch %s?"
> +msgstr "ブランチ%sが一意リビジョンを含む。\nそれでも削除しますか?"
ブランチ%sには他ブランチにマージされていないコミットがあります。それでも・・・
> +#: gitk:9934
> +msgid ""
> +"Sorry, gitk cannot run with this version of Tcl/Tk.\n"
> +" Gitk requires at least Tcl/Tk 8.4."
> +msgstr ""
> +"gitkは現在のTcl/Tkバージョンでは実行できません。\n"
> +"Tcl/Tkバージョン8.4はgitkの最低条件です。"
Gitk には最低 Tcl/Tkバージョン8.4が必要です。
> +#: gitk:10098
> +#, tcl-format
> +msgid "Ambiguous argument '%s': both revision and filename"
> +msgstr "多義引数'%s':リビジョンでもファイル名でもあります"
引数'%s'は曖昧です:・・・
^ permalink raw reply
* Re: [PATCH 2/2] pack-objects: report actual number of threads to be used
From: Dan McGee @ 2009-04-06 2:09 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Jeff King, git
In-Reply-To: <alpine.LFD.2.00.0904042001540.6741@xanadu.home>
On Sat, Apr 4, 2009 at 7:11 PM, Nicolas Pitre <nico@cam.org> wrote:
> On Sat, 4 Apr 2009, Jeff King wrote:
>
>> On Sat, Apr 04, 2009 at 01:20:18PM -0500, Dan McGee wrote:
>>
>> > > That makes sense to me, though I wonder if it may confuse and frustrate
>> > > users who are expecting their awesome quad-core machine to be using 4
>> > > threads when it only uses 2. Is it worth printing both values, or some
>> > > indicator that we could have been using more?
>> >
>> > I thought of this, but decided it wasn't really worth it. The default
>> > window size of 10 makes it a very rare case that you will use fewer
>> > than 4 threads. With the default, each thread needs a minimum of 20
>> > objects, so even a 100-object repository would spawn the 4 threads.
>>
>> Good point. Though by that logic, isn't your patch also not worth it
>> (i.e., it is unlikely not to fill the threads, so the output will be the
>> same with or without it)?
>>
>> I still think yours is an improvement, though, however slight.
>
> I don't think this is worth it at all.
>
> This display is there mainly to confirm expected number of available
> threads. The number of actually active threads is an implementation
> detail. Sure if the number of objects is too low, or if the window size
> is too large, then the number of active threads will be lower. But in
> practice it is also possible that with some patological object set you
> end up with 2 threads out of 4 completing very quickly and the other 2
> threads still busy with big objects and total remaining work set too
> small to split it further amongst idle threads, meaning that you'll end
> up with only 2 busy CPUs even though the display said 4 threads
> initially even with this patch.
>
> In other words I don't think this patch is a good idea as we don't
> update the display with remaining active threads along the way.
Why do we show this misleading at best piece of information at all
then? I'd rather completely remove it than show lies to the user. It
sounds like it is only there for debugging purposes.
If we choose to keep it, I propose either accepting my patch so we are
not mislead, or dropping the thread count completely from the output
and saying only something like "Using multi-threaded delta
compression."
-Dan
^ permalink raw reply
* Re: Segfault on merge with 1.6.2.1
From: Michael Johnson @ 2009-04-06 2:29 UTC (permalink / raw)
To: Clemens Buchacher, git; +Cc: Miklos Vajna, Johannes Schindelin
In-Reply-To: <1238892420-721-1-git-send-email-drizzd@aon.at>
On Sat, 04 Apr 2009 19:46:57 -0500, Clemens Buchacher <drizzd@aon.at>
wrote:
> The segmentation fault is caused by a null pointer dereference which
> happens during recursive merge with a submodule conflict between two
> merge bases. This is fixed by the following patches.
Amazingly I follow that. And the tracing I was doing now makes sense. I
saw the null pointer dereference, but couldn't figure out why. The
submodule conflict explains some things about what was going on in the
tree.
> +# history
> +#
> +# a --- c
> +# / \ /
> +# root X
> +# \ / \
> +# b --- d
This also explains a lot. Is there any way to get this sort of simplified
representation from the existing tools? I would think gitk would show it,
but would I be able to recognize it.?
> However, there are other problems with merging submodules. For example,
> git diff aborts with "fatal: read error 'sub'" for conflicting
> submodules.
> I have also added a test for this.
I believe there's a GSoC proposal that would help with this... from what I
read of it, it could prove very helpful to my workflow.
Anyway, thanks for all the help. I'll merge the patches in locally and see
if they work for me when I get a bit of time. I'm sure they will... it's
just for my own peace of mind.
Thanks again,
Michael
--
Michael D Johnson <redbeard@mdjohnson.us>
redbeardcreator.deviantart.com
"Marketing research...[has] shown that energy weapons that make sounds sell
better..." - Kevin Siembieda (Rifts Game Master Guide, pg 111)
^ permalink raw reply
* Re: [PATCH 2/2] pack-objects: report actual number of threads to be used
From: Nicolas Pitre @ 2009-04-06 2:31 UTC (permalink / raw)
To: Dan McGee; +Cc: Jeff King, git
In-Reply-To: <449c10960904051909v5ec5d7danc10d13d9a1d613f0@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2871 bytes --]
On Sun, 5 Apr 2009, Dan McGee wrote:
> On Sat, Apr 4, 2009 at 7:11 PM, Nicolas Pitre <nico@cam.org> wrote:
> > On Sat, 4 Apr 2009, Jeff King wrote:
> >
> >> On Sat, Apr 04, 2009 at 01:20:18PM -0500, Dan McGee wrote:
> >>
> >> > > That makes sense to me, though I wonder if it may confuse and frustrate
> >> > > users who are expecting their awesome quad-core machine to be using 4
> >> > > threads when it only uses 2. Is it worth printing both values, or some
> >> > > indicator that we could have been using more?
> >> >
> >> > I thought of this, but decided it wasn't really worth it. The default
> >> > window size of 10 makes it a very rare case that you will use fewer
> >> > than 4 threads. With the default, each thread needs a minimum of 20
> >> > objects, so even a 100-object repository would spawn the 4 threads.
> >>
> >> Good point. Though by that logic, isn't your patch also not worth it
> >> (i.e., it is unlikely not to fill the threads, so the output will be the
> >> same with or without it)?
> >>
> >> I still think yours is an improvement, though, however slight.
> >
> > I don't think this is worth it at all.
> >
> > This display is there mainly to confirm expected number of available
> > threads. The number of actually active threads is an implementation
> > detail. Sure if the number of objects is too low, or if the window size
> > is too large, then the number of active threads will be lower. But in
> > practice it is also possible that with some patological object set you
> > end up with 2 threads out of 4 completing very quickly and the other 2
> > threads still busy with big objects and total remaining work set too
> > small to split it further amongst idle threads, meaning that you'll end
> > up with only 2 busy CPUs even though the display said 4 threads
> > initially even with this patch.
> >
> > In other words I don't think this patch is a good idea as we don't
> > update the display with remaining active threads along the way.
>
> Why do we show this misleading at best piece of information at all
> then? I'd rather completely remove it than show lies to the user.
As you might imagine, I don't share your above appreciation.
> It
> sounds like it is only there for debugging purposes.
... which is still worthwhile nevertheless.
> If we choose to keep it, I propose either accepting my patch so we are
> not mislead, or dropping the thread count completely from the output
> and saying only something like "Using multi-threaded delta
> compression."
Your patch is not better. Instead, it will confuse people who
explicitly told git to use x threads but the display might say x-y
threads, with 0 <= y < x.
The number currently displayed has real meaning: this is the number of
threads git is allowed to use. The number of threads it will actually
use is variable and it changes with time.
Nicolas
^ permalink raw reply
* Re: [PATCH 2/2] pack-objects: report actual number of threads to be used
From: Dan McGee @ 2009-04-06 2:34 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Jeff King, git
In-Reply-To: <alpine.LFD.2.00.0904052220060.6741@xanadu.home>
On Sun, Apr 5, 2009 at 9:31 PM, Nicolas Pitre <nico@cam.org> wrote:
> On Sun, 5 Apr 2009, Dan McGee wrote:
>
>> On Sat, Apr 4, 2009 at 7:11 PM, Nicolas Pitre <nico@cam.org> wrote:
>> > On Sat, 4 Apr 2009, Jeff King wrote:
>> >
>> >> On Sat, Apr 04, 2009 at 01:20:18PM -0500, Dan McGee wrote:
>> >>
>> >> > > That makes sense to me, though I wonder if it may confuse and frustrate
>> >> > > users who are expecting their awesome quad-core machine to be using 4
>> >> > > threads when it only uses 2. Is it worth printing both values, or some
>> >> > > indicator that we could have been using more?
>> >> >
>> >> > I thought of this, but decided it wasn't really worth it. The default
>> >> > window size of 10 makes it a very rare case that you will use fewer
>> >> > than 4 threads. With the default, each thread needs a minimum of 20
>> >> > objects, so even a 100-object repository would spawn the 4 threads.
>> >>
>> >> Good point. Though by that logic, isn't your patch also not worth it
>> >> (i.e., it is unlikely not to fill the threads, so the output will be the
>> >> same with or without it)?
>> >>
>> >> I still think yours is an improvement, though, however slight.
>> >
>> > I don't think this is worth it at all.
>> >
>> > This display is there mainly to confirm expected number of available
>> > threads. The number of actually active threads is an implementation
>> > detail. Sure if the number of objects is too low, or if the window size
>> > is too large, then the number of active threads will be lower. But in
>> > practice it is also possible that with some patological object set you
>> > end up with 2 threads out of 4 completing very quickly and the other 2
>> > threads still busy with big objects and total remaining work set too
>> > small to split it further amongst idle threads, meaning that you'll end
>> > up with only 2 busy CPUs even though the display said 4 threads
>> > initially even with this patch.
>> >
>> > In other words I don't think this patch is a good idea as we don't
>> > update the display with remaining active threads along the way.
>>
>> Why do we show this misleading at best piece of information at all
>> then? I'd rather completely remove it than show lies to the user.
>
> As you might imagine, I don't share your above appreciation.
>
>> It
>> sounds like it is only there for debugging purposes.
>
> ... which is still worthwhile nevertheless.
>
>> If we choose to keep it, I propose either accepting my patch so we are
>> not mislead, or dropping the thread count completely from the output
>> and saying only something like "Using multi-threaded delta
>> compression."
>
> Your patch is not better. Instead, it will confuse people who
> explicitly told git to use x threads but the display might say x-y
> threads, with 0 <= y < x.
>
> The number currently displayed has real meaning: this is the number of
> threads git is allowed to use. The number of threads it will actually
> use is variable and it changes with time.
Would something like this be more ideal then? I wouldn't be so
persistent here if the current text wasn't misleading in a case like
the following:
dmcgee@galway ~/projects/devtools (master)
$ git push origin
Counting objects: 13, done.
Delta compression using 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (8/8), 1.28 KiB, done.
Total 8 (delta 6), reused 0 (delta 0)
To archlinux.org:/srv/projects/git/devtools.git
bcb0e39..ea73c2b master -> master
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 9fc3b35..99181fd 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1612,7 +1612,7 @@ static void ll_find_deltas(struct object_entry
**list, unsigned list_size,
return;
}
if (progress > pack_to_stdout)
- fprintf(stderr, "Delta compression using %d threads.\n",
+ fprintf(stderr, "Delta compression using up to %d threads.\n",
delta_search_threads);
/* Partition the work amongst work threads. */
^ permalink raw reply related
* [PATCH] Documentation: clarify .gitattributes search
From: Jason Merrill @ 2009-04-06 2:43 UTC (permalink / raw)
To: git, gitster
[-- Attachment #1: Type: text/plain, Size: 1 bytes --]
[-- Attachment #2: 0001-Documentation-clarify-.gitattributes-search.patch --]
[-- Type: text/x-patch, Size: 1432 bytes --]
>From 04b504dc0c174d697cc1b75829fe2f7473f193ce Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Sun, 5 Apr 2009 21:54:37 -0400
Subject: [PATCH] Documentation: clarify .gitattributes search
Signed-off-by: Jason Merrill <jason@redhat.com>
---
As discussed on IRC today; I was wondering if my home directory qualified
as a parent directory, but apparently not.
Documentation/gitattributes.txt | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 55668e3..0338385 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -60,9 +60,9 @@ same as in `.gitignore` files; see linkgit:gitignore[5].
When deciding what attributes are assigned to a path, git
consults `$GIT_DIR/info/attributes` file (which has the highest
precedence), `.gitattributes` file in the same directory as the
-path in question, and its parent directories (the further the
-directory that contains `.gitattributes` is from the path in
-question, the lower its precedence).
+path in question, and its parent directories within the git repository
+(the further the directory that contains `.gitattributes` is from the
+path in question, the lower its precedence).
If you wish to affect only a single repository (i.e., to assign
attributes to files that are particular to one user's workflow), then
--
1.6.2.2
^ permalink raw reply related
* Re: Performance issue: initial git clone causes massive repack
From: Nguyen Thai Ngoc Duy @ 2009-04-06 3:10 UTC (permalink / raw)
To: Robin H. Johnson; +Cc: Git Mailing List
In-Reply-To: <20090405T230552Z@curie.orbis-terrarum.net>
On Mon, Apr 6, 2009 at 9:38 AM, Robin H. Johnson <robbat2@gentoo.org> wrote:
> Looking at the source, I agree that it should be buffering, however top and ps
> seem to disagree. 3GiB VSZ and 2.5GiB RSS here now.
>
> %CPU %MEM VSZ RSS STAT START TIME COMMAND
> 0.0 0.0 140932 1040 Ss 16:09 0:00 \_ git-upload-pack /code/gentoo/gentoo-git/gentoo-x86.git
> 32.2 0.0 0 0 Z 16:09 1:50 \_ [git-upload-pack] <defunct>
> 80.8 44.2 3018484 2545700 Sl 16:09 4:36 \_ git pack-objects --stdout --progress --delta-base-offset
>
> Also, I did another trace, using some other hardware, in a LAN setting, and
> noticed that git-upload-pack/pack-objects only seems to start output to the
> network after it reaches 100% in 'remote: Compressing objects:'.
>
> Relatedly, throwing more RAM (6GiB total, vs. the previous 2GiB) at the server
> in this case cut the 200 wallclock minutes before any sending too place down to
> 5 minutes.
Searching back the archive, there was memory fragmentation issue with
gcc repo. I wonder if it happens again. Maybe you should try Google
allocator. BTW, did you try to turn off THREADED_DELTA_SEARCH?
--
Duy
^ permalink raw reply
* Re: [PATCH 2/2] pack-objects: report actual number of threads to be used
From: Nicolas Pitre @ 2009-04-06 3:14 UTC (permalink / raw)
To: Dan McGee; +Cc: Jeff King, git
In-Reply-To: <449c10960904051934l54d2d504w1af867dc53ef7dd7@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1516 bytes --]
On Sun, 5 Apr 2009, Dan McGee wrote:
> On Sun, Apr 5, 2009 at 9:31 PM, Nicolas Pitre <nico@cam.org> wrote:
> > The number currently displayed has real meaning: this is the number of
> > threads git is allowed to use. The number of threads it will actually
> > use is variable and it changes with time.
>
> Would something like this be more ideal then? I wouldn't be so
> persistent here if the current text wasn't misleading in a case like
> the following:
>
> dmcgee@galway ~/projects/devtools (master)
> $ git push origin
> Counting objects: 13, done.
> Delta compression using 4 threads.
> Compressing objects: 100% (8/8), done.
> Writing objects: 100% (8/8), 1.28 KiB, done.
> Total 8 (delta 6), reused 0 (delta 0)
> To archlinux.org:/srv/projects/git/devtools.git
> bcb0e39..ea73c2b master -> master
>
> diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
> index 9fc3b35..99181fd 100644
> --- a/builtin-pack-objects.c
> +++ b/builtin-pack-objects.c
> @@ -1612,7 +1612,7 @@ static void ll_find_deltas(struct object_entry
> **list, unsigned list_size,
> return;
> }
> if (progress > pack_to_stdout)
> - fprintf(stderr, "Delta compression using %d threads.\n",
> + fprintf(stderr, "Delta compression using up to %d threads.\n",
> delta_search_threads);
>
> /* Partition the work amongst work threads. */
This I have absolutely no issue with.
Acked-by: Nicolas Pitre <nico@cam.org>
Nicolas
^ permalink raw reply
* Re: Performance issue: initial git clone causes massive repack
From: Nicolas Pitre @ 2009-04-06 3:24 UTC (permalink / raw)
To: Sverre Rabbelier
Cc: david, Junio C Hamano, Nicolas Sebrecht, Robin H. Johnson,
Git Mailing List
In-Reply-To: <fabb9a1e0904051436i1dc9c1bdhe86a23e470c756f9@mail.gmail.com>
On Sun, 5 Apr 2009, Sverre Rabbelier wrote:
> Heya,
>
> On Sun, Apr 5, 2009 at 23:28, <david@lang.hm> wrote:
> > Guys, back off a little on telling the gentoo people to change.
>
> I agree here, we should either say "look, we don't really support big
> repositories because [explanation here], unless you [workarounds
> here]" OR we should work to improve the support we do have. Of course,
> the latter option does not magically create developer time to work on
> that, but if we do go that way we should at least tell people that we
> are aware of the problems and that it's on the global TODO list (not
> necessarily on anyone's personal TODO list though).
For the record... I at least am aware of the problem and it is indeed on
my personal git todo list. Not that I have a clear solution yet (I've
been pondering on some git packing issues for almost 4 years now).
Still, in this particular case, the problem appears to be unclear to me,
like "this shouldn't be so bad".
> Of course, the problem can sometimes be solved by splitting the
> repository, but I think it is important to have an official policy
> here, do we want Git to support huge repositories, or do we not?
I do.
Nicolas
^ permalink raw reply
* Re: [RFC/PATCH 0/2] New 'stage' command
From: David Aguilar @ 2009-04-06 3:24 UTC (permalink / raw)
To: Sverre Rabbelier; +Cc: markus.heidelberg, Felipe Contreras, git, Junio C Hamano
In-Reply-To: <fabb9a1e0904051622k66352ea4v542ecd99bd5d9c6@mail.gmail.com>
On 0, Sverre Rabbelier <srabbelier@gmail.com> wrote:
> Heya,
>
> On Mon, Apr 6, 2009 at 01:17, Markus Heidelberg
> <markus.heidelberg@web.de> wrote:
> > Felipe Contreras, 06.04.2009:
> >> But actually, "git diff --cached" is a
> >> different action; you can't do "git diff --cached HEAD^.." for
> >> example.
> >
> > And I neither could I do "git stage diff HEAD^.."
>
> I rest my case ;). That's the whole point Felipe is trying to make here.
> $ git diff --cached
> $ git diff HEAD^..
>
> That's two different modes of operation with the only difference being
> a switch ('--cached'), which changes what is, and what is not valid
> after that.
>
> Whereas with
> $ git stage diff
>
> There is no confusion that 'HEAD^..' is not a valid argument, as there
> is no command in 'git stage diff' to which it _is_ a valid argument.
Hello
Here's an interesting email from a while back:
http://kerneltrap.org/mailarchive/git/2008/10/29/3857134
The above mentions the following suggestion:
git diff STAGE WORKTREE (like "git diff" today)
git diff HEAD WORKTREE (like "git diff HEAD" today)
git diff WORKTREE HEAD (like "git diff -R HEAD" today)
git diff HEAD STAGE (like "git diff --cached" today)
git diff commit STAGE (like "git diff --cached commit" today)
>From a consistency and usability perspective, the above
example seems very appealing because:
a) it does not introduce any new commands, and
b) it is consistent with the way git-diff's command-line
interface works today.
All we'd have to do is teach git-diff to special-case
'STAGE' and 'WORKTREE'. Now, whether we'd want to do
that is a completely different discussion, but I figured I'd
throw the old thread out there.
--
David
^ permalink raw reply
* Re: Performance issue: initial git clone causes massive repack
From: Nicolas Pitre @ 2009-04-06 3:34 UTC (permalink / raw)
To: david; +Cc: Nicolas Sebrecht, Robin H. Johnson, Git Mailing List
In-Reply-To: <alpine.DEB.1.10.0904051613420.6245@asgard.lang.hm>
On Sun, 5 Apr 2009, david@lang.hm wrote:
> On Mon, 6 Apr 2009, Nicolas Sebrecht wrote:
>
> > On Sun, Apr 05, 2009 at 02:28:35PM -0700, david@lang.hm wrote:
> >
> > > guys, back off a little on telling the gentoo people to change.
> >
> > Don't blame Git people, please. I currently am the only one here to
> > discuss that way and see a painful work coming at Gentoo.
> > Git people didn't discuss around thoses issues.
> >
> > > the
> > > kernel developers don't split th kernel into 'core' 'drivers' etc pieces
> > > just because some people only work on one area.
> >
> > And you might notice that they don't provide a CVS access and actually
> > don't work around an unique shared repo. Also, you might notice that
> > keeping the history clean to assure the work on the kernel easier is not
> > an elementary issue.
>
> these issues are completely seperate from the issue that the initial poster
> asked about, which is that when someone tries to do a clone of the repository
> the system wastes a lot of time creating a new pack.
And this shouldn't be, by design. Especially if your repo serving clone
requests is already well packed.
What git-pack-objects does in this case is not a full repack. It
instead _reuse_ as much of the existing packs as possible, and only does
the heavy packing processing for loose objects and/or inter pack
boundaryes when gluing everything together for streaming over the net.
If for example you have a single pack because your repo is already fully
packed, then the "packing operation" involved during a clone should
merely copy the existing pack over with no further attempt at delta
compression.
> don't worry about this part of things, worry about why the server wastes so
> many resources.
Indeed. And since a significant amount of code involved happens to be
mine, I do wonder.
Nicolas
^ permalink raw reply
* Re: Performance issue: initial git clone causes massive repack
From: Nicolas Pitre @ 2009-04-06 4:06 UTC (permalink / raw)
To: Robin H. Johnson; +Cc: Git Mailing List
In-Reply-To: <20090405T230552Z@curie.orbis-terrarum.net>
On Sun, 5 Apr 2009, Robin H. Johnson wrote:
> On Sun, Apr 05, 2009 at 03:57:14PM -0400, Jeff King wrote:
> > > During an initial clone, I see that git-upload-pack invokes
> > > pack-objects, despite the ENTIRE repository already being packed - no
> > > loose objects whatsoever. git-upload-pack then seems to buffer in
> > > memory.
> > We need to run pack-objects even if the repo is fully packed because we
> > don't know what's _in_ the existing pack (or packs). In particular we
> > want to:
> > - combine multiple packs into a single pack; this is more efficient on
> > the network, because you can find more deltas, and I believe is
> > required because the protocol sends only a single pack.
> >
> > - cull any objects which are not actually part of the reachability
> > chain from the refs we are sending
> >
> > If no work needs to be done for either case, then pack-objects should
> > basically just figure that out and then send the existing pack (the
> > expensive bit is doing deltas, and we don't consider objects in the same
> > pack for deltas, as we know we have already considered that during the
> > last repack). It does mmap the whole pack, so you will see your virtual
> > memory jump, but nothing should require the whole pack being in memory
> > at once.
Actually the pack is mapped with a (configurable) window. See the
core.packedGitWindowSize and core.packedGitLimit config options for
details.
> While my current pack setup has multiple packs of not more than 100MiB
> each, that was simply for ease of resume with rsync+http tests. Even
> when I already had a single pack, with every object reachable,
> pack-objects was redoing the packing.
In that case it shouldn't have.
> > pack-objects streams the output to upload-pack, which should only ever
> > have an 8K buffer of it in memory at any given time.
> >
> > At least that is how it is all supposed to work, according to my
> > understanding. So if you are seeing very high memory usage, I wonder if
> > there is a bug in pack-objects or upload-pack that can be fixed.
> >
> > Maybe somebody more knowledgeable than me about packing can comment.
> Looking at the source, I agree that it should be buffering, however top and ps
> seem to disagree. 3GiB VSZ and 2.5GiB RSS here now.
>
> %CPU %MEM VSZ RSS STAT START TIME COMMAND
> 0.0 0.0 140932 1040 Ss 16:09 0:00 \_ git-upload-pack /code/gentoo/gentoo-git/gentoo-x86.git
> 32.2 0.0 0 0 Z 16:09 1:50 \_ [git-upload-pack] <defunct>
> 80.8 44.2 3018484 2545700 Sl 16:09 4:36 \_ git pack-objects --stdout --progress --delta-base-offset
>
> Also, I did another trace, using some other hardware, in a LAN setting, and
> noticed that git-upload-pack/pack-objects only seems to start output to the
> network after it reaches 100% in 'remote: Compressing objects:'.
That's to be expected. Delta compression matches objects which are not
in the stream order at all. Therefore it is not possible to start
outputting pack data until this pass is done. Still, this pass should
not be invoked if your repository is already fully packed into one pack.
Can you confirm this is actually the case?
> Relatedly, throwing more RAM (6GiB total, vs. the previous 2GiB) at
> the server in this case cut the 200 wallclock minutes before any
> sending too place down to 5 minutes.
Well... here's a wild guess. In the source repository serving clone
requests, please do:
git config pack.deltaCacheSize 1
git config pack.deltaCacheLimit 0
and try cloning again with a fully packed repository.
> > > For the initial clone, can the git-upload-pack algorithm please send
> > > existing packs, and only generate a pack containing the non-packed
> > > items?
> >
> > I believe that would require a change to the protocol to allow multiple
> > packs. However, it may be possible to munge the pack header in such a
> > way that you basically concatenate multiple packs. You would still want
> > to peek in the big pack to try deltas from the non-packed items, though.
As explained already, even if the protocol requires a single pack to be
created, it is still made up of unmodified data segments from existing
packs as much as possible. So you should see it more or less as the
concatenation of those packs already, plus some munging over the edges.
> > I think all of this falls into the realm of the GSOC pack caching project.
> > There have been other discussions on the list, so you might want to look
> > through those for something useful.
> Yes, both changing the protocol, and recognizing that existing packs may be
> suitable to send could be considered as part of the caching project, as they
> fall under the aegis of making good use of what's stored in the cache already
> to send.
The caching pack project is to address a different issue: mainly to
bypass the object enumeration cost. In other words, it could allow for
skipping the "Counting objects" pass, and a tiny bit more. At least in
theory that's about the main difference. This has many drawbacks as
well though.
Nicolas
^ permalink raw reply
* Re: Performance issue: initial git clone causes massive repack
From: Nicolas Pitre @ 2009-04-06 4:09 UTC (permalink / raw)
To: Nguyen Thai Ngoc Duy; +Cc: Robin H. Johnson, Git Mailing List
In-Reply-To: <fcaeb9bf0904052010p34e3246bwd7e1f5297acf37e2@mail.gmail.com>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1462 bytes --]
On Mon, 6 Apr 2009, Nguyen Thai Ngoc Duy wrote:
> On Mon, Apr 6, 2009 at 9:38 AM, Robin H. Johnson <robbat2@gentoo.org> wrote:
> > Looking at the source, I agree that it should be buffering, however top and ps
> > seem to disagree. 3GiB VSZ and 2.5GiB RSS here now.
> >
> > %CPU %MEM VSZ RSS STAT START TIME COMMAND
> > 0.0 0.0 140932 1040 Ss 16:09 0:00 \_ git-upload-pack /code/gentoo/gentoo-git/gentoo-x86.git
> > 32.2 0.0 0 0 Z 16:09 1:50 \_ [git-upload-pack] <defunct>
> > 80.8 44.2 3018484 2545700 Sl 16:09 4:36 \_ git pack-objects --stdout --progress --delta-base-offset
> >
> > Also, I did another trace, using some other hardware, in a LAN setting, and
> > noticed that git-upload-pack/pack-objects only seems to start output to the
> > network after it reaches 100% in 'remote: Compressing objects:'.
> >
> > Relatedly, throwing more RAM (6GiB total, vs. the previous 2GiB) at the server
> > in this case cut the 200 wallclock minutes before any sending too place down to
> > 5 minutes.
>
> Searching back the archive, there was memory fragmentation issue with
> gcc repo. I wonder if it happens again. Maybe you should try Google
> allocator. BTW, did you try to turn off THREADED_DELTA_SEARCH?
That was for a _full_ repack, i.e. 'git repack -a -f'. This is never
the case on a fetch/clone, like in this case, unless you have all your
objects in loose form.
Nicolas
^ permalink raw reply
* Re: [question] how can i verify whether a local branch is tracking a remote branch?
From: Jeff King @ 2009-04-06 4:34 UTC (permalink / raw)
To: Paolo Ciarrocchi; +Cc: git
In-Reply-To: <4d8e3fd30904051425w6739a12fp5666e71e8b2d7958@mail.gmail.com>
On Sun, Apr 05, 2009 at 11:25:29PM +0200, Paolo Ciarrocchi wrote:
> An example:
> $ git clone -n URL temp
> $ cd temp
> $ git branch -r
> origin/master
> origin/foo
> Origin/bar
> $ git checkout --track -b foo origin/foo
>
> Now, how can I know that foo is tracking origin/foo ?
Doing it right is hard. You have to:
1. check branch.foo.merge and branch.foo.rebase; if no value, it is not
tracking anything; if it is, remember that value as $m
2. check branch.foo.remote for the remote name, $r
3. check the fetch refspecs for remote $r; these can come from
the config, or from .git/remotes/* files. Maybe even .git/branches
files; I don't even remember how those work.
4. find the refspec that fetches from $m; then find the matching
destination for that refspec. That is the tracking branch.
E.g., in your example (and using a modern git):
1. $m is refs/heads/foo
2. $r is origin
3. The fetch refspec is in remote.origin.fetch, and is generally
"refs/heads/*:refs/remotes/origin/*"
4. So refs/heads/foo becomes refs/remotes/origin/foo.
refs/remotes/origin/foo is your tracking branch.
Steps 1 and 2 are easy, but 3 and 4 are a bit nasty. You can fake it by
assuming that "refs/heads/$m" on "$r" is always "refs/remotes/$r/$m",
which is true for very vanilla setups.
There is C code that does this, but there is not a good way of accessing
it from the command-line. The best you can do is "git remote show
origin", which on recent git versions should show something like:
...
Local branches configured for 'git pull':
foo merges with remote foo
...
But of course that implies that you already guessed the remote "origin".
And it's not using plumbing, so it's not very suitable for scripts.
I don't think it would be unreasonable to expose this functionality via
"for-each-ref". Something like this (which would need cleanup,
documentation, and perhaps a :short variant):
---
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index 5cbb4b0..3f418e4 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -8,6 +8,7 @@
#include "blob.h"
#include "quote.h"
#include "parse-options.h"
+#include "remote.h"
/* Quoting styles */
#define QUOTE_NONE 0
@@ -66,6 +67,7 @@ static struct {
{ "subject" },
{ "body" },
{ "contents" },
+ { "tracking" },
};
/*
@@ -699,6 +701,18 @@ static void populate_value(struct refinfo *ref)
v->s = s;
}
}
+ if (!strcmp(name, "tracking")) {
+ struct branch *branch;
+ if (prefixcmp(ref->refname, "refs/heads/"))
+ continue;
+ branch = branch_get(ref->refname + 11);
+ if (branch && branch->merge && branch->merge[0] &&
+ branch->merge[0]->dst)
+ v->s = branch->merge[0]->dst;
+ else
+ v->s = NULL;
+ free(branch); /* XXX should also free other parts? */
+ }
}
grab_values(ref->value, 0, obj, buf, size);
>
> Thanks.
>
>
> Ciao,
> --
> Paolo
> http://paolo.ciarrocchi.googlepages.com/
> http://mypage.vodafone.it/
^ permalink raw reply related
* Re: Performance issue: initial git clone causes massive repack
From: Junio C Hamano @ 2009-04-06 5:15 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: david, Nicolas Sebrecht, Robin H. Johnson, Git Mailing List
In-Reply-To: <alpine.LFD.2.00.0904052326090.6741@xanadu.home>
Nicolas Pitre <nico@cam.org> writes:
> What git-pack-objects does in this case is not a full repack. It
> instead _reuse_ as much of the existing packs as possible, and only does
> the heavy packing processing for loose objects and/or inter pack
> boundaryes when gluing everything together for streaming over the net.
> If for example you have a single pack because your repo is already fully
> packed, then the "packing operation" involved during a clone should
> merely copy the existing pack over with no further attempt at delta
> compression.
One possibile scenario that you still need to spend memory and cycle is if
the cloned repository was packed to an excessive depth to cause many of
its objects to be in deltified form on insanely deep chains, while cloning
send-pack uses a depth that is more reasonable. Then pack-objects invoked
by send-pack is not allowed to reuse most of the objects and would end up
redoing the delta on them.
^ 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