* Re: [PATCH] Make cvsexportcommit work with filenames containing spaces.
From: Junio C Hamano @ 2006-09-23 19:03 UTC (permalink / raw)
To: Robin Rosenberg; +Cc: git
In-Reply-To: <200609231427.55721.robin.rosenberg@dewire.com>
Robin Rosenberg <robin.rosenberg@dewire.com> writes:
> Why patch? Well this patch works around (i.e. not perfect) a mismatch between
> what patch eats and git submits. They are not totally, compatible, and I'm
> not sure who to blame yet. git emits diff's without timestamps, and what
> matters to patch, without a TAB before the file timestamp. When patch sees a
> header like "+++ filename with spaces.txt" it patches "filename". When it
> sees "+++ filename with spaces.txt<TAB>" if patches "filename with
> spaces.txt". The real fix would ofcourse be in git diff or patch sometime in
> the future.
Ah, it might be because our diff output do not have trailing TAB
(and timestamp) and if CVS uses GNU patch that would be confused
and not detect the file being patched.
Interestingly, I did a two-patch series to address that issue
separately. But that is not even in "next" yet.
More interestingly, the version of "GNU patch" that cannot grok
our patch (without trailing TAB) for a file that has SP in its
name is on my home machine where your patched cvsexportcommit
works. I do not know if GNU patch on the other machine does.
Will collect necessary info and follow up.
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Jakub Narebski @ 2006-09-23 18:45 UTC (permalink / raw)
To: git
In-Reply-To: <20060923164308.16334.49252.stgit@machine.or.cz>
Petr Baudis wrote:
> This patch enables fetching multiple repositories at once over the Git
> protocol (and SSH, and locally if git-fetch-pack is your cup of coffee
> there). This is done especially for the xorg people who have tons of
> repositories and dislike pulls much slower than they were used to with CVS.
> I'm eager to hear how this affects the situation.
[...]
I see that objects got to the one shared object database. Where the heads
(refs) go to? Separate projects have separate ref spaces, even if they share
object database...
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply
* [PATCH] Git.pm: Kill Git.xs for now
From: Petr Baudis @ 2006-09-23 18:20 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch removes Git.xs from the repository for the time being. This
should hopefully enable Git.pm to finally make its way to master.
Git.xs is not going away forever. When the Git libification makes some
progress, it will hopefully return (but most likely as an optional
component, due to the portability woes) since the performance boosts are
really important for applications like Gitweb or Cogito. It needs to go
away now since it is not really reliable in case you use it for several
repositories in the scope of a single process, and that is not possible
to fix without some either very ugly or very intrusive core changes.
Rest in peace. (While you can.)
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
Makefile | 17 ++-----
perl/.gitignore | 3 -
perl/Git.pm | 76 ++++---------------------------
perl/Git.xs | 134 ------------------------------------------------------
perl/Makefile.PL | 9 ----
5 files changed, 15 insertions(+), 224 deletions(-)
diff --git a/Makefile b/Makefile
index dd74908..58848e4 100644
--- a/Makefile
+++ b/Makefile
@@ -116,8 +116,6 @@ PIC_FLAG = -fPIC
LDFLAGS =
ALL_CFLAGS = $(CFLAGS)
ALL_LDFLAGS = $(LDFLAGS)
-PERL_CFLAGS =
-PERL_LDFLAGS =
STRIP ?= strip
prefix = $(HOME)
@@ -158,9 +156,10 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powe
### --- END CONFIGURATION SECTION ---
# Those must not be GNU-specific; they are shared with perl/ which may
-# be built by a different compiler.
-BASIC_CFLAGS = $(PERL_CFLAGS)
-BASIC_LDFLAGS = $(PERL_LDFLAGS)
+# be built by a different compiler. (Note that this is an artifact now
+# but it still might be nice to keep that distinction.)
+BASIC_CFLAGS =
+BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-branch.sh git-checkout.sh \
@@ -784,15 +783,9 @@ XDIFF_OBJS=xdiff/xdiffi.o xdiff/xprepare
rm -f $@ && $(AR) rcs $@ $(XDIFF_OBJS)
-PERL_DEFINE = $(BASIC_CFLAGS) -DGIT_VERSION='"$(GIT_VERSION)"'
-PERL_DEFINE_SQ = $(subst ','\'',$(PERL_DEFINE))
-PERL_LIBS = $(BASIC_LDFLAGS) $(EXTLIBS)
-PERL_LIBS_SQ = $(subst ','\'',$(PERL_LIBS))
perl/Makefile: perl/Git.pm perl/Makefile.PL GIT-CFLAGS
(cd perl && $(PERL_PATH) Makefile.PL \
- PREFIX='$(prefix_SQ)' \
- DEFINE='$(PERL_DEFINE_SQ)' \
- LIBS='$(PERL_LIBS_SQ)')
+ PREFIX='$(prefix_SQ)')
doc:
$(MAKE) -C Documentation all
diff --git a/perl/.gitignore b/perl/.gitignore
index 6d778f3..e990cae 100644
--- a/perl/.gitignore
+++ b/perl/.gitignore
@@ -1,7 +1,4 @@
-Git.bs
-Git.c
Makefile
blib
blibdirs
pm_to_blib
-ppport.h
diff --git a/perl/Git.pm b/perl/Git.pm
index 9ce9fcd..2b26b65 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -93,9 +93,6 @@ use Carp qw(carp croak); # but croak is
use Error qw(:try);
use Cwd qw(abs_path);
-require XSLoader;
-XSLoader::load('Git', $VERSION);
-
}
@@ -413,12 +410,13 @@ sub command_noisy {
Return the Git version in use.
-Implementation of this function is very fast; no external command calls
-are involved.
-
=cut
-# Implemented in Git.xs.
+sub version {
+ my $verstr = command_oneline('--version');
+ $verstr =~ s/^git version //;
+ $verstr;
+}
=item exec_path ()
@@ -426,12 +424,9 @@ # Implemented in Git.xs.
Return path to the Git sub-command executables (the same as
C<git --exec-path>). Useful mostly only internally.
-Implementation of this function is very fast; no external command calls
-are involved.
-
=cut
-# Implemented in Git.xs.
+sub exec_path { command_oneline('--exec-path') }
=item repo_path ()
@@ -572,41 +567,21 @@ sub ident_person {
=item hash_object ( TYPE, FILENAME )
-=item hash_object ( TYPE, FILEHANDLE )
-
Compute the SHA1 object id of the given C<FILENAME> (or data waiting in
C<FILEHANDLE>) considering it is of the C<TYPE> object type (C<blob>,
C<commit>, C<tree>).
-In case of C<FILEHANDLE> passed instead of file name, all the data
-available are read and hashed, and the filehandle is automatically
-closed. The file handle should be freshly opened - if you have already
-read anything from the file handle, the results are undefined (since
-this function works directly with the file descriptor and internal
-PerlIO buffering might have messed things up).
-
The method can be called without any instance or on a specified Git repository,
it makes zero difference.
The function returns the SHA1 hash.
-Implementation of this function is very fast; no external command calls
-are involved.
-
=cut
+# TODO: Support for passing FILEHANDLE instead of FILENAME
sub hash_object {
my ($self, $type, $file) = _maybe_self(@_);
-
- # hash_object_* implemented in Git.xs.
-
- if (ref($file) eq 'GLOB') {
- my $hash = hash_object_pipe($type, fileno($file));
- close $file;
- return $hash;
- } else {
- hash_object_file($type, $file);
- }
+ command_oneline('hash-object', '-t', $type, $file);
}
@@ -802,7 +777,7 @@ sub _cmd_exec {
# Execute the given Git command ($_[0]) with arguments ($_[1..])
# by searching for it at proper places.
-# _execv_git_cmd(), implemented in Git.xs.
+sub _execv_git_cmd { exec('git', @_); }
# Close pipe to a subprocess.
sub _cmd_close {
@@ -821,39 +796,6 @@ sub _cmd_close {
}
-# Trickery for .xs routines: In order to avoid having some horrid
-# C code trying to do stuff with undefs and hashes, we gate all
-# xs calls through the following and in case we are being ran upon
-# an instance call a C part of the gate which will set up the
-# environment properly.
-sub _call_gate {
- my $xsfunc = shift;
- my ($self, @args) = _maybe_self(@_);
-
- if (defined $self) {
- # XXX: We ignore the WorkingCopy! To properly support
- # that will require heavy changes in libgit.
-
- # XXX: And we ignore everything else as well. libgit
- # at least needs to be extended to let us specify
- # the $GIT_DIR instead of looking it up in environment.
- #xs_call_gate($self->{opts}->{Repository});
- }
-
- # Having to call throw from the C code is a sure path to insanity.
- local $SIG{__DIE__} = sub { throw Error::Simple("@_"); };
- &$xsfunc(@args);
-}
-
-sub AUTOLOAD {
- my $xsname;
- our $AUTOLOAD;
- ($xsname = $AUTOLOAD) =~ s/.*:://;
- throw Error::Simple("&Git::$xsname not defined") if $xsname =~ /^xs_/;
- $xsname = 'xs_'.$xsname;
- _call_gate(\&$xsname, @_);
-}
-
sub DESTROY { }
diff --git a/perl/Git.xs b/perl/Git.xs
deleted file mode 100644
index 2bbec43..0000000
--- a/perl/Git.xs
+++ /dev/null
@@ -1,134 +0,0 @@
-/* By carefully stacking #includes here (even if WE don't really need them)
- * we strive to make the thing actually compile. Git header files aren't very
- * nice. Perl headers are one of the signs of the coming apocalypse. */
-#include <ctype.h>
-/* Ok, it hasn't been so bad so far. */
-
-/* libgit interface */
-#include "../cache.h"
-#include "../exec_cmd.h"
-
-/* XS and Perl interface */
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-
-
-static char *
-report_xs(const char *prefix, const char *err, va_list params)
-{
- static char buf[4096];
- strcpy(buf, prefix);
- vsnprintf(buf + strlen(prefix), 4096 - strlen(prefix), err, params);
- return buf;
-}
-
-static void NORETURN
-die_xs(const char *err, va_list params)
-{
- char *str;
- str = report_xs("fatal: ", err, params);
- croak(str);
-}
-
-static void
-error_xs(const char *err, va_list params)
-{
- char *str;
- str = report_xs("error: ", err, params);
- warn(str);
-}
-
-
-MODULE = Git PACKAGE = Git
-
-PROTOTYPES: DISABLE
-
-
-BOOT:
-{
- set_error_routine(error_xs);
- set_die_routine(die_xs);
-}
-
-
-# /* TODO: xs_call_gate(). See Git.pm. */
-
-
-char *
-xs_version()
-CODE:
-{
- RETVAL = GIT_VERSION;
-}
-OUTPUT:
- RETVAL
-
-
-char *
-xs_exec_path()
-CODE:
-{
- RETVAL = (char *)git_exec_path();
-}
-OUTPUT:
- RETVAL
-
-
-void
-xs__execv_git_cmd(...)
-CODE:
-{
- const char **argv;
- int i;
-
- argv = malloc(sizeof(const char *) * (items + 1));
- if (!argv)
- croak("malloc failed");
- for (i = 0; i < items; i++)
- argv[i] = strdup(SvPV_nolen(ST(i)));
- argv[i] = NULL;
-
- execv_git_cmd(argv);
-
- for (i = 0; i < items; i++)
- if (argv[i])
- free((char *) argv[i]);
- free((char **) argv);
-}
-
-char *
-xs_hash_object_pipe(type, fd)
- char *type;
- int fd;
-CODE:
-{
- unsigned char sha1[20];
-
- if (index_pipe(sha1, fd, type, 0))
- croak("Unable to hash given filehandle");
- RETVAL = sha1_to_hex(sha1);
-}
-OUTPUT:
- RETVAL
-
-char *
-xs_hash_object_file(type, path)
- char *type;
- char *path;
-CODE:
-{
- unsigned char sha1[20];
- int fd = open(path, O_RDONLY);
- struct stat st;
-
- if (fd < 0 ||
- fstat(fd, &st) < 0 ||
- index_fd(sha1, fd, &st, 0, type))
- croak("Unable to hash %s", path);
- close(fd);
-
- RETVAL = sha1_to_hex(sha1);
-}
-OUTPUT:
- RETVAL
diff --git a/perl/Makefile.PL b/perl/Makefile.PL
index ef9d82d..de73235 100644
--- a/perl/Makefile.PL
+++ b/perl/Makefile.PL
@@ -3,12 +3,7 @@ use ExtUtils::MakeMaker;
sub MY::postamble {
return <<'MAKE_FRAG';
instlibdir:
- @echo '$(INSTALLSITEARCH)'
-
-check:
- perl -MDevel::PPPort -le 'Devel::PPPort::WriteFile(".ppport.h")' && \
- perl .ppport.h --compat-version=5.6.0 Git.xs && \
- rm .ppport.h
+ @echo '$(INSTALLSITELIB)'
MAKE_FRAG
}
@@ -29,7 +24,5 @@ WriteMakefile(
NAME => 'Git',
VERSION_FROM => 'Git.pm',
PM => \%pm,
- MYEXTLIB => '../libgit.a',
- INC => '-I. -I..',
%extra
);
^ permalink raw reply related
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Johannes Schindelin @ 2006-09-23 18:14 UTC (permalink / raw)
To: Petr Baudis; +Cc: A Large Angry SCM, Junio C Hamano, git
In-Reply-To: <20060923180539.GC20017@pasky.or.cz>
Hi,
On Sat, 23 Sep 2006, Petr Baudis wrote:
> Hi!
>
> Dear diary, on Sat, Sep 23, 2006 at 07:54:10PM CEST, I got a letter
> where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> > On Sat, 23 Sep 2006, Petr Baudis wrote:
> >
> > > Dear diary, on Sat, Sep 23, 2006 at 07:23:01PM CEST, I got a letter
> > > where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> > > > I still firmly believe that it would be way more efficient to fetch all
> > > > those branches into _one_ proxy repository. Especially since you can reuse
> > > > the objects with an alternate, which has an additional benefit over your
> > > > approach.
> > >
> > > Huh? You can reuse the objects with my approach as well. Actually, it
> > > is automagically done so.
> > >
> > > With proxy repository, you would still need a server-side setup to
> > > maintain that repository, and specialized client-side porcelain to fetch
> > > from it. My approach initially requires some core changes (which aren't
> > > very pretty as it is but are not very fundamental or logically intrusive
> > > either) but in the longer run it pays off since you don't need a
> > > convoluted server-side setup for that.
> >
> > No, you do not need _any_ server-side setup. And you do not need any
> > specialized client-side porcelain other than a script, which just does
> > the job.
>
> So how should the proxy repository be set up at the server side? I can
> just imagine a cronjob periodically sweeping the repositories and
> populate the proxy repository with new stuff (refs and objects) from
> those.
>
> Looking at what you wrote again, you talk about fetching all those
> branches _into_ one proxy repository. Perhaps we misunderstand each
> other. This patch is not about the "into" part, it is about being able
> to fetch _FROM_ _multiple_ repositories.
Indeed, I misunderstood.
Hmmm. Did you test if this makes things better? If so, could you test with
one proxy repo on the server? I bet that this would be even more
efficient.
And the proxy repo would be updated best by a hook, not a cronjob.
The thing is, your patch optimizes for a very special case, which special
case IMHO should be handled differently to begin with.
Ciao,
Dscho
^ permalink raw reply
* Re: The GPL: No shelter for the Linux kernel?
From: Petr Baudis @ 2006-09-23 18:14 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Jan Engelhardt, David Schwartz, linux-kernel, git
In-Reply-To: <Pine.LNX.4.64.0609231051570.4388@g5.osdl.org>
(Quoting in full for the git@ people.)
Dear diary, on Sat, Sep 23, 2006 at 08:00:23PM CEST, I got a letter
where Linus Torvalds <torvalds@osdl.org> said that...
> On Sat, 23 Sep 2006, Jan Engelhardt wrote:
> >
> > Now that you raise it: I think developers can already have done that
> > if they wish - properly name author and conditions who may possibly
> > change the license to what. Not that I have seen such code yet, but you
> > never know.
>
> Side note: in "git", we kind of discussed this. And because the project
> was started when the whole GPL version discussion was already in bloom,
> the git project has a note at top of the COPYING file that says:
>
> Note that the only valid version of the GPL as far as this project
> is concerned is _this_ particular version of the license (ie v2, not
> v2.2 or v3.x or whatever), unless explicitly otherwise stated.
>
> HOWEVER, in order to allow a migration to GPLv3 if that seems like
> a good idea, I also ask that people involved with the project make
> their preferences known. In particular, if you trust me to make that
> decision, you might note so in your copyright message, ie something
> like
>
> This file is licensed under the GPL v2, or a later version
> at the discretion of Linus.
>
> might avoid issues. But we can also just decide to synchronize and
> contact all copyright holders on record if/when the occasion arises.
>
> but note how it's still at the discretion of the actual developers (ie
> when you add a file, you can either not specify any extensions, in which
> case it's "GPLv2 only", or you can specify "GPLv2 or any later", or you
> can specify the "GPLv2 or any later at the discretion of Linus Torvalds".
>
> The silly thing, of course, is that I'm not even the maintainer any more,
> and that Junio has done a kick-ass job of maintaining the thing, and is
> definitely the main author by now. So the whole "discretion of Linus" is a
> bit insane.
>
> [ Although exactly _because_ Junio has been such a great maintainer, I'd
> bow down to whatever decision he does, so my "discretion" would be to
> let him decide, if he wanted to. At some point, you have to trust some
> people, and just let go - if they do more than you do, they damn well
> have more rights than you do too. "Maintainership has its privileges" ]
>
> Anyway, I suspect the git language was a mistake. We should just have done
> what the kernel did - make the version number be clear and fixed, so that
> people don't even have to worry about exactly what conditions might cause
> a relicensing to happen.
Actually, this didn't catch on very well anyway, I guess because most
people just know it's GPLv2 and don't even bother to peek at COPYING, we
are a bit sloppy about copyright notices and most of them don't mention
licence at all (if there are any in the file at all), and adding
explicit copyright notices to mails isn't too popular either.
$ git grep 'discretion'
COPYING: at the discretion of Linus.
git-annotate.perl:# at the discretion of Linus Torvalds.
git-relink.perl:# Later versions of the GPL at the discretion of Linus Torvalds
git-request-pull.sh:# at the discretion of Linus Torvalds.
and I've found no patches with such special assignment.
I think people don't really want to bother with thinking too much
about licences at all unless absolutely necessary, they just want to do
the fun part (coding). :-)
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-09-23 18:05 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: A Large Angry SCM, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0609231947340.25853@wbgn013.biozentrum.uni-wuerzburg.de>
Hi!
Dear diary, on Sat, Sep 23, 2006 at 07:54:10PM CEST, I got a letter
where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> On Sat, 23 Sep 2006, Petr Baudis wrote:
>
> > Dear diary, on Sat, Sep 23, 2006 at 07:23:01PM CEST, I got a letter
> > where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> > > I still firmly believe that it would be way more efficient to fetch all
> > > those branches into _one_ proxy repository. Especially since you can reuse
> > > the objects with an alternate, which has an additional benefit over your
> > > approach.
> >
> > Huh? You can reuse the objects with my approach as well. Actually, it
> > is automagically done so.
> >
> > With proxy repository, you would still need a server-side setup to
> > maintain that repository, and specialized client-side porcelain to fetch
> > from it. My approach initially requires some core changes (which aren't
> > very pretty as it is but are not very fundamental or logically intrusive
> > either) but in the longer run it pays off since you don't need a
> > convoluted server-side setup for that.
>
> No, you do not need _any_ server-side setup. And you do not need any
> specialized client-side porcelain other than a script, which just does
> the job.
So how should the proxy repository be set up at the server side? I can
just imagine a cronjob periodically sweeping the repositories and
populate the proxy repository with new stuff (refs and objects) from
those.
Looking at what you wrote again, you talk about fetching all those
branches _into_ one proxy repository. Perhaps we misunderstand each
other. This patch is not about the "into" part, it is about being able
to fetch _FROM_ _multiple_ repositories.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Johannes Schindelin @ 2006-09-23 17:54 UTC (permalink / raw)
To: Petr Baudis; +Cc: A Large Angry SCM, Junio C Hamano, git
In-Reply-To: <20060923173943.GA20017@pasky.or.cz>
Hi,
On Sat, 23 Sep 2006, Petr Baudis wrote:
> Dear diary, on Sat, Sep 23, 2006 at 07:23:01PM CEST, I got a letter
> where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> > On Sat, 23 Sep 2006, Petr Baudis wrote:
> >
> > > Dear diary, on Sat, Sep 23, 2006 at 06:57:36PM CEST, I got a letter
> > > where A Large Angry SCM <gitzilla@gmail.com> said that...
> > > > Petr Baudis wrote:
> > > > >You still need to pass git-fetch-pack some URL in addition to the
> > > > >repositories - it is used only for git_connect(), the purpose is that
> > > > >repositories must be local directories so if you want to talk remote, you
> > > > >need to do something like
> > > > >
> > > > > git-fetch-pack git://kernel.org/pub/scm/git/git.git
> > > > > --repo=/pub/scm/git/git.git master next
> > > > > --repo=/pub/scm/cogito/cogito.git master
> > > > >
> > > >
> > > > Can't this be done with a simple wrapper around git-fetch* ?
> > >
> > > The point is that that is too slow (the difference is noticeable
> > > especiall in the case there is no new stuff ready), you need to create a
> > > connection and do whole lot of work for each of the repositories.
> >
> > I still firmly believe that it would be way more efficient to fetch all
> > those branches into _one_ proxy repository. Especially since you can reuse
> > the objects with an alternate, which has an additional benefit over your
> > approach.
>
> Huh? You can reuse the objects with my approach as well. Actually, it
> is automagically done so.
>
> With proxy repository, you would still need a server-side setup to
> maintain that repository, and specialized client-side porcelain to fetch
> from it. My approach initially requires some core changes (which aren't
> very pretty as it is but are not very fundamental or logically intrusive
> either) but in the longer run it pays off since you don't need a
> convoluted server-side setup for that.
No, you do not need _any_ server-side setup. And you do not need any
specialized client-side porcelain other than a script, which just does
the job.
The point is, your changes are not only intrusive, they are unnecessary.
You can even declare the first repository as the proxy. Sketch of script:
- find which branches are wanted at all,
- do the fetch (of all wanted branches) in the first repository,
storing the refs under refs/multi/,
- for each repository
- ensure that the first repo is given as alternative
- store the branches this repo wants (you only need to
update the refs, since you have all the objects)
This is not particularly complicated, is it?
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC][PATCH] for_each_ref() returning heads in wrong order
From: Petr Baudis @ 2006-09-23 17:42 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, torvalds, git
In-Reply-To: <Pine.LNX.4.63.0609231919510.25853@wbgn013.biozentrum.uni-wuerzburg.de>
Hi,
Dear diary, on Sat, Sep 23, 2006 at 07:20:42PM CEST, I got a letter
where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> On Sat, 23 Sep 2006, Petr Baudis wrote:
>
> > Dear diary, on Sat, Sep 23, 2006 at 06:36:21PM CEST, I got a letter
> > where Petr Baudis <pasky@suse.cz> said that...
> > > Using the #next branch I've now hit a problem with git-fetch-pack
> > > master choosing refs/bases/master (I geuss created by StGIT) instead
> > > of refs/heads/master. The old upload-pack returned the refs in the order
> > > heads-tags-everything_else but the new one just goes for whatever order
> > > readdir() returns them in (modulo merging with packed refs). I actually
> > > can't see the difference that caused this right now, though.
>
> Why don't you just specify (or match) "heads/refs/master", so that
> git-fetch-pack cannot choose anything wrong to begin with?
hmm, does git-fetch prepend refs/heads/ to the refspecs or does it
pass them as is to git-fetch-pack?
If the former, then we could as well do that, but in that case I'd
rather just require that for any refs passed to git-fetch-pack since
passing the "short form" just serves for buggy scripts to get confused
when someone adds some refs directory that sorts before heads/ to the
repository.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-09-23 17:39 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: A Large Angry SCM, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.63.0609231921110.25853@wbgn013.biozentrum.uni-wuerzburg.de>
Hi,
Dear diary, on Sat, Sep 23, 2006 at 07:23:01PM CEST, I got a letter
where Johannes Schindelin <Johannes.Schindelin@gmx.de> said that...
> On Sat, 23 Sep 2006, Petr Baudis wrote:
>
> > Dear diary, on Sat, Sep 23, 2006 at 06:57:36PM CEST, I got a letter
> > where A Large Angry SCM <gitzilla@gmail.com> said that...
> > > Petr Baudis wrote:
> > > >You still need to pass git-fetch-pack some URL in addition to the
> > > >repositories - it is used only for git_connect(), the purpose is that
> > > >repositories must be local directories so if you want to talk remote, you
> > > >need to do something like
> > > >
> > > > git-fetch-pack git://kernel.org/pub/scm/git/git.git
> > > > --repo=/pub/scm/git/git.git master next
> > > > --repo=/pub/scm/cogito/cogito.git master
> > > >
> > >
> > > Can't this be done with a simple wrapper around git-fetch* ?
> >
> > The point is that that is too slow (the difference is noticeable
> > especiall in the case there is no new stuff ready), you need to create a
> > connection and do whole lot of work for each of the repositories.
>
> I still firmly believe that it would be way more efficient to fetch all
> those branches into _one_ proxy repository. Especially since you can reuse
> the objects with an alternate, which has an additional benefit over your
> approach.
Huh? You can reuse the objects with my approach as well. Actually, it
is automagically done so.
With proxy repository, you would still need a server-side setup to
maintain that repository, and specialized client-side porcelain to fetch
from it. My approach initially requires some core changes (which aren't
very pretty as it is but are not very fundamental or logically intrusive
either) but in the longer run it pays off since you don't need a
convoluted server-side setup for that.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Johannes Schindelin @ 2006-09-23 17:23 UTC (permalink / raw)
To: Petr Baudis; +Cc: A Large Angry SCM, Junio C Hamano, git
In-Reply-To: <20060923170439.GQ8259@pasky.or.cz>
Hi,
On Sat, 23 Sep 2006, Petr Baudis wrote:
> Dear diary, on Sat, Sep 23, 2006 at 06:57:36PM CEST, I got a letter
> where A Large Angry SCM <gitzilla@gmail.com> said that...
> > Petr Baudis wrote:
> > >You still need to pass git-fetch-pack some URL in addition to the
> > >repositories - it is used only for git_connect(), the purpose is that
> > >repositories must be local directories so if you want to talk remote, you
> > >need to do something like
> > >
> > > git-fetch-pack git://kernel.org/pub/scm/git/git.git
> > > --repo=/pub/scm/git/git.git master next
> > > --repo=/pub/scm/cogito/cogito.git master
> > >
> >
> > Can't this be done with a simple wrapper around git-fetch* ?
>
> The point is that that is too slow (the difference is noticeable
> especiall in the case there is no new stuff ready), you need to create a
> connection and do whole lot of work for each of the repositories.
I still firmly believe that it would be way more efficient to fetch all
those branches into _one_ proxy repository. Especially since you can reuse
the objects with an alternate, which has an additional benefit over your
approach.
And _then_, you can make a wrapper script, which guarantees that the
alternate is set, and that the ref is actually fetched from the proxy.
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC][PATCH] for_each_ref() returning heads in wrong order
From: Johannes Schindelin @ 2006-09-23 17:20 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, torvalds, git
In-Reply-To: <20060923164759.GP8259@pasky.or.cz>
Hi,
On Sat, 23 Sep 2006, Petr Baudis wrote:
> Dear diary, on Sat, Sep 23, 2006 at 06:36:21PM CEST, I got a letter
> where Petr Baudis <pasky@suse.cz> said that...
> > Using the #next branch I've now hit a problem with git-fetch-pack
> > master choosing refs/bases/master (I geuss created by StGIT) instead
> > of refs/heads/master. The old upload-pack returned the refs in the order
> > heads-tags-everything_else but the new one just goes for whatever order
> > readdir() returns them in (modulo merging with packed refs). I actually
> > can't see the difference that caused this right now, though.
Why don't you just specify (or match) "heads/refs/master", so that
git-fetch-pack cannot choose anything wrong to begin with?
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC][PATCH] for_each_ref() returning heads in wrong order
From: Linus Torvalds @ 2006-09-23 17:12 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, git
In-Reply-To: <20060923160712.5890.73139.stgit@machine.or.cz>
On Sat, 23 Sep 2006, Petr Baudis wrote:
>
> Using the #next branch I've now hit a problem with git-fetch-pack
> master choosing refs/bases/master (I geuss created by StGIT) instead
> of refs/heads/master. The old upload-pack returned the refs in the order
> heads-tags-everything_else but the new one just goes for whatever order
> readdir() returns them in (modulo merging with packed refs). I actually
> can't see the difference that caused this right now, though.
Actually, I think it's exactly the other way around.
The _old_ "for_each_refs()" returned things in a totally random order,
depending on the readdir(). On many (but not all) filesystems, that ends
up being somewhat decided by the order the entries were created in, so for
example, you'd generally get "refs/heads/" and "refs/tags/" early
(discounting HEAD, which is always a special case and comes first).
The _new_ thing is totally reliable. It returns things sorted
alphabetically according to "strcmp". It doesn't matter what ordering
readdir() gives.
Now, we could change the sorting order artificially, but I think your
patch is actually incorrect. Because you no longer sort the list
appropriately, the merge-sort done by "do_show_each_ref()" is no longer
guaranteed to work, I think.
Ugly.
The proper way to fix it (if you want to do this at all) is to just define
the sort-order to be something else than a plain "strcmp()", and change
the things that compare ordering to just use the new ordering instead.
In other words, start from something like THIS, and just change
"ref_name_compare()" to taste. Make sure it's a complete ordering, though.
Linus
---
diff --git a/refs.c b/refs.c
index 2cef2b4..05b7006 100644
--- a/refs.c
+++ b/refs.c
@@ -37,6 +37,17 @@ static const char *parse_ref_line(char *
return line;
}
+/*
+ * This is the ordering function for refnames. It has the
+ * same semantics as "strcmp()", but you can define it to
+ * order "refs/heads/" and "refs/tags/" before other names,
+ * for example.
+ */
+static int ref_name_compare(const char *a, const char *b)
+{
+ return strcmp(a,b);
+}
+
static struct ref_list *add_ref(const char *name, const unsigned char *sha1,
int flag, struct ref_list *list)
{
@@ -45,7 +56,7 @@ static struct ref_list *add_ref(const ch
/* Find the place to insert the ref into.. */
while ((entry = *p) != NULL) {
- int cmp = strcmp(entry->name, name);
+ int cmp = ref_name_compare(entry->name, name);
if (cmp > 0)
break;
@@ -179,7 +190,7 @@ const char *resolve_ref(const char *ref,
if (lstat(path, &st) < 0) {
struct ref_list *list = get_packed_refs();
while (list) {
- if (!strcmp(ref, list->name)) {
+ if (!ref_name_compare(ref, list->name)) {
hashcpy(sha1, list->sha1);
if (flag)
*flag |= REF_ISPACKED;
@@ -297,7 +308,7 @@ static int do_for_each_ref(const char *b
while (packed && loose) {
struct ref_list *entry;
- int cmp = strcmp(packed->name, loose->name);
+ int cmp = ref_name_compare(packed->name, loose->name);
if (!cmp) {
packed = packed->next;
continue;
^ permalink raw reply related
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-09-23 17:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <20060923164308.16334.49252.stgit@machine.or.cz>
[-- Attachment #1: Type: text/plain, Size: 1016 bytes --]
Dear diary, on Sat, Sep 23, 2006 at 06:45:09PM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
> You still need to pass git-fetch-pack some URL in addition to the
> repositories - it is used only for git_connect(), the purpose is that
> repositories must be local directories so if you want to talk remote, you
> need to do something like
>
> git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master
..snip..
> The main target of this are the Xorg people who have plenty of small repos
> and frequently want to update many of them. It would be nice if someone
> from Xorg reading this and concerned with this could measure the
> difference.
Attached is a simple porcelain script for this.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
[-- Attachment #2: multifetch.pl --]
[-- Type: text/x-perl, Size: 1265 bytes --]
#!/usr/bin/perl
use warnings;
use strict;
# Remember that you must ensure the obj database is shared - either symlink it
# or setup alternates!
#my $remoteurl = 'git://git.kernel.org/pub/scm/git/git.git';
#my %config = (
# '/pub/scm/git/git.git' => {
# 'next' => {
# '/home/xpasky/q/gg' => 'origin'
# },
# 'master' => {
# '/home/xpasky/q/gg' => 'origin2',
# '/home/xpasky/q/gg2' => 'origin'
# }
# },
# '/pub/scm/cogito/cogito-doc.git' => {
# master => {
# '/home/xpasky/q/gg2' => 'origin2'
# }
# }
#);
my $remoteurl = 'puturlofremotehosthere';
my %config = (
'remoterepo1' => {
branch1 => {
'localrepo1' => 'origin'
},
branch2 => {
'localrepo1' => 'origin2',
'localrepo2' => 'origin'
}
},
'remoterepo2' => {
master => {
'localrepo2' => 'origin2'
}
}
);
my @args = ($remoteurl);
foreach my $repo (keys %config) {
push (@args, '--repo='.$repo);
foreach my $branch (keys %{$config{$repo}}) {
push (@args, $branch);
}
}
open (F, '-|', 'git-fetch-pack', @args) or die "$!";
while (<F>) {
chomp;
split / /, $_;
my ($sha, $ref, $repo) = @_;
$ref =~ s#^refs/heads/##;
foreach my $lrepo (keys %{$config{$repo}->{$ref}}) {
system("GIT_DIR=$lrepo git-update-ref $config{$repo}->{$ref}->{$lrepo} $sha");
}
}
close (F);
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-09-23 17:04 UTC (permalink / raw)
To: A Large Angry SCM; +Cc: Junio C Hamano, git
In-Reply-To: <45156780.6070801@gmail.com>
Dear diary, on Sat, Sep 23, 2006 at 06:57:36PM CEST, I got a letter
where A Large Angry SCM <gitzilla@gmail.com> said that...
> Petr Baudis wrote:
> >You still need to pass git-fetch-pack some URL in addition to the
> >repositories - it is used only for git_connect(), the purpose is that
> >repositories must be local directories so if you want to talk remote, you
> >need to do something like
> >
> > git-fetch-pack git://kernel.org/pub/scm/git/git.git
> > --repo=/pub/scm/git/git.git master next
> > --repo=/pub/scm/cogito/cogito.git master
> >
>
> Can't this be done with a simple wrapper around git-fetch* ?
The point is that that is too slow (the difference is noticeable
especiall in the case there is no new stuff ready), you need to create a
connection and do whole lot of work for each of the repositories.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* Re: [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: A Large Angry SCM @ 2006-09-23 16:57 UTC (permalink / raw)
To: Petr Baudis; +Cc: Junio C Hamano, git
In-Reply-To: <20060923164308.16334.49252.stgit@machine.or.cz>
Petr Baudis wrote:
> This patch enables fetching multiple repositories at once over the Git
> protocol (and SSH, and locally if git-fetch-pack is your cup of coffee
> there). This is done especially for the xorg people who have tons of
> repositories and dislike pulls much slower than they were used to with CVS.
> I'm eager to hear how this affects the situation.
>
> It's kind of "superproject" thing, basically, taking reverse approach than
> the subproject ideas. However, in practice I think it can be used for
> subprojects quite well and perhaps if I find some spare time during the day
> I will add the lightweight subproject support to Cogito, using this.
>
> So, you need some kind of porcelain for this. The idea is that instead of
> telling git-fetch-pack a single repository, you pass multiple --repo=
> parameters and refs always "belong" to the latest mentioned repository;
> when outputting the new ref values, the appropriate repo is mentioned near
> each ref. In order for this to be useful, on your local side you should
> share the objects database in some way - either using alternates (then
> you must fetch to an object database reachable from everywhere) or symlinked
> object databases.
>
> You still need to pass git-fetch-pack some URL in addition to the
> repositories - it is used only for git_connect(), the purpose is that
> repositories must be local directories so if you want to talk remote, you
> need to do something like
>
> git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master
>
Can't this be done with a simple wrapper around git-fetch* ?
^ permalink raw reply
* Re: [RFC][PATCH] for_each_ref() returning heads in wrong order
From: Petr Baudis @ 2006-09-23 16:47 UTC (permalink / raw)
To: Junio C Hamano; +Cc: torvalds, git
In-Reply-To: <20060923160712.5890.73139.stgit@machine.or.cz>
Dear diary, on Sat, Sep 23, 2006 at 06:36:21PM CEST, I got a letter
where Petr Baudis <pasky@suse.cz> said that...
> Using the #next branch I've now hit a problem with git-fetch-pack
> master choosing refs/bases/master (I geuss created by StGIT) instead
> of refs/heads/master. The old upload-pack returned the refs in the order
> heads-tags-everything_else but the new one just goes for whatever order
> readdir() returns them in (modulo merging with packed refs). I actually
> can't see the difference that caused this right now, though.
Portion of this is obsolete, I've since noticed what the difference
actually is - the _old_ one processed the directory unsorted and the new
one actually keeps it sorted in add_ref().
Alternate approach would be just to modify add_ref() sort order to take
heads and tags into account (but you still need to keep the cmp hack for
merging packed/loose refs). Should be pretty easy to do, but I
personally need to proceed with my TODO list for now since I've already
a working workaround.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* [RFC][RESEND][PATCH] Allow fetching from multiple repositories at once
From: Petr Baudis @ 2006-09-23 16:45 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
This patch enables fetching multiple repositories at once over the Git
protocol (and SSH, and locally if git-fetch-pack is your cup of coffee
there). This is done especially for the xorg people who have tons of
repositories and dislike pulls much slower than they were used to with CVS.
I'm eager to hear how this affects the situation.
It's kind of "superproject" thing, basically, taking reverse approach than
the subproject ideas. However, in practice I think it can be used for
subprojects quite well and perhaps if I find some spare time during the day
I will add the lightweight subproject support to Cogito, using this.
So, you need some kind of porcelain for this. The idea is that instead of
telling git-fetch-pack a single repository, you pass multiple --repo=
parameters and refs always "belong" to the latest mentioned repository;
when outputting the new ref values, the appropriate repo is mentioned near
each ref. In order for this to be useful, on your local side you should
share the objects database in some way - either using alternates (then
you must fetch to an object database reachable from everywhere) or symlinked
object databases.
You still need to pass git-fetch-pack some URL in addition to the
repositories - it is used only for git_connect(), the purpose is that
repositories must be local directories so if you want to talk remote, you
need to do something like
git-fetch-pack git://kernel.org/pub/scm/git/git.git --repo=/pub/scm/git/git.git master next --repo=/pub/scm/cogito/cogito.git master
The implementation is, well... rather hackish to say the least. :-)
We can do something nicer if it turns out to be a boost huge enough
in reality too.
The main target of this are the Xorg people who have plenty of small repos
and frequently want to update many of them. It would be nice if someone
from Xorg reading this and concerned with this could measure the
difference.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
This is an even more awful hack than the previous version, because of
did_refs. I wonder how ugly would it be to have that in stock Git
version, or if there's a good way to eliminate that hack before
proceeding with full libification.
This is a second resend. The first one was from the end of July but
flyed by with not much of a response.
cache.h | 7 ++++-
connect.c | 11 +++++---
daemon.c | 9 +++++--
fetch-pack.c | 58 ++++++++++++++++++++++++++++++---------------
path.c | 5 ++++
peek-remote.c | 4 ++-
refs.c | 6 ++---
send-pack.c | 4 ++-
sha1_file.c | 6 ++---
upload-pack.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++--------
10 files changed, 136 insertions(+), 48 deletions(-)
diff --git a/cache.h b/cache.h
index a7f673d..59cf0ed 100644
--- a/cache.h
+++ b/cache.h
@@ -240,6 +240,7 @@ int git_config_perm(const char *var, con
int adjust_shared_perm(const char *path);
int safe_create_leading_directories(char *path);
char *enter_repo(char *path, int strict);
+int security_repo_check(int export_all_trees);
/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
extern int sha1_object_info(const unsigned char *, char *, unsigned long *);
@@ -332,6 +333,7 @@ extern struct alternate_object_database
char base[FLEX_ARRAY]; /* more */
} *alt_odb_list;
extern void prepare_alt_odb(void);
+extern int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth, int allow_self);
extern struct packed_git {
struct packed_git *next;
@@ -359,6 +361,7 @@ struct ref {
unsigned char new_sha1[20];
unsigned char force;
struct ref *peer_ref; /* when renaming */
+ char *repo; /* when doing multi-repo operations */
char name[FLEX_ARRAY]; /* more */
};
@@ -368,11 +371,11 @@ #define REF_TAGS (1u << 2)
extern pid_t git_connect(int fd[2], char *url, const char *prog);
extern int finish_connect(pid_t pid);
-extern int path_match(const char *path, int nr, char **match);
+extern int path_match(const char *path, const char *repo, int nr, char **match, char **match_repo);
extern int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
int nr_refspec, char **refspec, int all);
extern int get_ack(int fd, unsigned char *result_sha1);
-extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags);
+extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, char *repo, unsigned int flags);
extern int server_supports(const char *feature);
extern struct packed_git *parse_pack_index(unsigned char *sha1);
diff --git a/connect.c b/connect.c
index c55a20a..0b62406 100644
--- a/connect.c
+++ b/connect.c
@@ -45,9 +45,8 @@ static int check_ref(const char *name, i
*/
struct ref **get_remote_heads(int in, struct ref **list,
int nr_match, char **match,
- unsigned int flags)
+ char *repo, unsigned int flags)
{
- *list = NULL;
for (;;) {
struct ref *ref;
unsigned char old_sha1[20];
@@ -74,11 +73,12 @@ struct ref **get_remote_heads(int in, st
if (!check_ref(name, name_len, flags))
continue;
- if (nr_match && !path_match(name, nr_match, match))
+ if (nr_match && !path_match(name, NULL, nr_match, match, NULL))
continue;
ref = xcalloc(1, sizeof(*ref) + len - 40);
hashcpy(ref->old_sha1, old_sha1);
memcpy(ref->name, buffer + 41, len - 40);
+ ref->repo = repo;
*list = ref;
list = &ref->next;
}
@@ -112,7 +112,8 @@ int get_ack(int fd, unsigned char *resul
die("git-fetch_pack: expected ACK/NAK, got '%s'", line);
}
-int path_match(const char *path, int nr, char **match)
+int path_match(const char *path, const char *repo, int nr, char **match,
+ char **match_repo)
{
int i;
int pathlen = strlen(path);
@@ -121,6 +122,8 @@ int path_match(const char *path, int nr,
char *s = match[i];
int len = strlen(s);
+ if (match_repo && repo != match_repo[i])
+ continue;
if (!len || len > pathlen)
continue;
if (memcmp(path + pathlen - len, s, len))
diff --git a/daemon.c b/daemon.c
index eb4f3f1..d0b44b2 100644
--- a/daemon.c
+++ b/daemon.c
@@ -321,8 +321,7 @@ static int run_service(struct interp *it
* path_ok() uses enter_repo() and does whitelist checking.
* We only need to make sure the repository is exported.
*/
-
- if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
+ if (!security_repo_check(export_all_trees)) {
logerror("'%s': repository not exported.", path);
errno = EACCES;
return -1;
@@ -355,11 +354,15 @@ static int upload_pack(void)
{
/* Timeout as string */
char timeout_buf[64];
+ char checkexport_buf[64];
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
+ strcpy(checkexport_buf, "--check-export");
+ if (export_all_trees) checkexport_buf[1] = '\0'; /* XXX */
+
/* git-upload-pack only ever reads stuff, so this is safe */
- execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
+ execl_git_cmd("upload-pack", "--strict", timeout_buf, checkexport_buf, ".", NULL);
return -1;
}
diff --git a/fetch-pack.c b/fetch-pack.c
index 99ac08b..edbdf19 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -282,7 +282,8 @@ static void mark_recent_complete_commits
}
}
-static void filter_refs(struct ref **refs, int nr_match, char **match)
+static void filter_refs(struct ref **refs, int nr_match, char **match,
+ char **match_repo)
{
struct ref **return_refs;
struct ref *newlist = NULL;
@@ -313,7 +314,7 @@ static void filter_refs(struct ref **ref
continue;
}
else {
- int order = path_match(ref->name, nr_match, match);
+ int order = path_match(ref->name, ref->repo, nr_match, match, match_repo);
if (order) {
return_refs[order-1] = ref;
continue; /* we will link it later */
@@ -338,7 +339,8 @@ static void filter_refs(struct ref **ref
*refs = newlist;
}
-static int everything_local(struct ref **refs, int nr_match, char **match)
+static int everything_local(struct ref **refs, int nr_match, char **match,
+ char **match_repo)
{
struct ref *ref;
int retval;
@@ -387,7 +389,7 @@ static int everything_local(struct ref *
}
}
- filter_refs(refs, nr_match, match);
+ filter_refs(refs, nr_match, match, match_repo);
for (retval = 1, ref = *refs; ref ; ref = ref->next) {
const unsigned char *remote = ref->old_sha1;
@@ -415,13 +417,15 @@ static int everything_local(struct ref *
return retval;
}
-static int fetch_pack(int fd[2], int nr_match, char **match)
+static int fetch_pack(int fd[2], int nr_repo, char **repo,
+ int nr_match, char **match, char **match_repo)
{
- struct ref *ref;
+ struct ref *ref = NULL, **refn;
unsigned char sha1[20];
int status;
+ int i;
- get_remote_heads(fd[0], &ref, 0, NULL, 0);
+ refn = get_remote_heads(fd[0], &ref, 0, NULL, nr_repo ? repo[0] : NULL, 0);
if (server_supports("multi_ack")) {
if (verbose)
fprintf(stderr, "Server supports multi_ack\n");
@@ -437,11 +441,19 @@ static int fetch_pack(int fd[2], int nr_
fprintf(stderr, "Server supports side-band\n");
use_sideband = 1;
}
+ if (!server_supports("switch-repo") && nr_repo > 1)
+ die("server does not support fetching multiple repositories at once");
+
+ for (i = 1; i < nr_repo; i++) {
+ packet_write(fd[1], "switch-repo %s", repo[i]);
+ refn = get_remote_heads(fd[0], refn, 0, NULL, repo[i], 0);
+ }
+
if (!ref) {
packet_flush(fd[1]);
die("no matching remote head");
}
- if (everything_local(&ref, nr_match, match)) {
+ if (everything_local(&ref, nr_match, match, match_repo)) {
packet_flush(fd[1]);
goto all_done;
}
@@ -462,8 +474,9 @@ static int fetch_pack(int fd[2], int nr_
all_done:
while (ref) {
- printf("%s %s\n",
- sha1_to_hex(ref->old_sha1), ref->name);
+ printf("%s %s%s%s\n",
+ sha1_to_hex(ref->old_sha1), ref->name,
+ ref->repo ? " " : "", ref->repo ? : "");
ref = ref->next;
}
return 0;
@@ -471,15 +484,16 @@ static int fetch_pack(int fd[2], int nr_
int main(int argc, char **argv)
{
- int i, ret, nr_heads;
- char *dest = NULL, **heads;
+ int i, ret, nr_repo = 0, nr_heads = 0;
+ char *dest = NULL;
+ char **repo = xmalloc(argc * sizeof(*repo));
+ char **heads = xmalloc(argc * sizeof(*heads));
+ char **heads_repo = xmalloc(argc * sizeof(*heads_repo));
int fd[2];
pid_t pid;
setup_git_directory();
- nr_heads = 0;
- heads = NULL;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -504,16 +518,22 @@ int main(int argc, char **argv)
fetch_all = 1;
continue;
}
+ if (!strncmp("--repo=", arg, 7)) {
+ repo[nr_repo++] = arg + 7;
+ continue;
+ }
if (!strcmp("-v", arg)) {
verbose = 1;
continue;
}
usage(fetch_pack_usage);
}
- dest = arg;
- heads = argv + i + 1;
- nr_heads = argc - i - 1;
- break;
+ if (!dest) {
+ dest = arg;
+ continue;
+ }
+ heads_repo[nr_heads] = nr_repo ? repo[nr_repo - 1] : NULL;
+ heads[nr_heads++] = arg;
}
if (!dest)
usage(fetch_pack_usage);
@@ -522,7 +542,7 @@ int main(int argc, char **argv)
pid = git_connect(fd, dest, exec);
if (pid < 0)
return 1;
- ret = fetch_pack(fd, nr_heads, heads);
+ ret = fetch_pack(fd, nr_repo, repo, nr_heads, heads, heads_repo);
close(fd[0]);
close(fd[1]);
ret |= finish_connect(pid);
diff --git a/path.c b/path.c
index bb89fb0..d669cac 100644
--- a/path.c
+++ b/path.c
@@ -251,6 +251,11 @@ char *enter_repo(char *path, int strict)
return NULL;
}
+int security_repo_check(int export_all_trees)
+{
+ return (export_all_trees || access("git-daemon-export-ok", F_OK));
+}
+
int adjust_shared_perm(const char *path)
{
struct stat st;
diff --git a/peek-remote.c b/peek-remote.c
index 353da00..2cf9e50 100644
--- a/peek-remote.c
+++ b/peek-remote.c
@@ -8,9 +8,9 @@ static const char *exec = "git-upload-pa
static int peek_remote(int fd[2], unsigned flags)
{
- struct ref *ref;
+ struct ref *ref = NULL;
- get_remote_heads(fd[0], &ref, 0, NULL, flags);
+ get_remote_heads(fd[0], &ref, 0, NULL, NULL, flags);
packet_flush(fd[1]);
while (ref) {
diff --git a/refs.c b/refs.c
index 9b3986a..10e588e 100644
--- a/refs.c
+++ b/refs.c
@@ -144,12 +144,12 @@ nextitem:;
return list;
}
+int did_read_loose_refs = 0;
static struct ref_list *get_loose_refs(void)
{
- static int did_refs = 0;
static struct ref_list *refs = NULL;
- if (!did_refs) {
+ if (!did_read_loose_refs) {
/* We need to make sure refs/heads and refs/tags always
* go before everything else. */
char *except[] = {"refs/heads", "refs/tags", NULL};
@@ -167,7 +167,7 @@ static struct ref_list *get_loose_refs(v
refs = other_refs;
}
- did_refs = 1;
+ did_read_loose_refs = 1;
}
return refs;
}
diff --git a/send-pack.c b/send-pack.c
index fbd792c..e1cf58b 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -266,14 +266,14 @@ static int receive_status(int in)
static int send_pack(int in, int out, int nr_refspec, char **refspec)
{
- struct ref *ref;
+ struct ref *ref = NULL;
int new_refs;
int ret = 0;
int ask_for_status_report = 0;
int expect_status_report = 0;
/* No funny business with the matcher */
- remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
+ remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, NULL, REF_NORMAL);
get_local_heads();
/* Does the other end support the reporting? */
diff --git a/sha1_file.c b/sha1_file.c
index 27b1ebb..14f06c9 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -235,7 +235,7 @@ static void read_info_alternates(const c
* SHA1, an extra slash for the first level indirection, and the
* terminating NUL.
*/
-static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
+int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth, int allow_self)
{
struct stat st;
const char *objdir = get_object_directory();
@@ -285,7 +285,7 @@ static int link_alt_odb_entry(const char
return -1;
}
}
- if (!memcmp(ent->base, objdir, pfxlen)) {
+ if (!allow_self && !memcmp(ent->base, objdir, pfxlen)) {
free(ent);
return -1;
}
@@ -331,7 +331,7 @@ static void link_alt_odb_entries(const c
relative_base, last);
} else {
link_alt_odb_entry(last, cp - last,
- relative_base, depth);
+ relative_base, depth, 0);
}
}
while (cp < ep && *cp == sep)
diff --git a/upload-pack.c b/upload-pack.c
index 4e53edd..57ae127 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -10,7 +10,7 @@ #include "object.h"
#include "commit.h"
#include "exec_cmd.h"
-static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] <dir>";
+static const char upload_pack_usage[] = "git-upload-pack [--strict] [--timeout=nn] [--check-export] <dir>";
/* bits #0..7 in revision.h, #8..10 in commit.c */
#define THEY_HAVE (1u << 11)
@@ -30,6 +30,8 @@ static unsigned int timeout;
* otherwise maximum packet size (up to 65520 bytes).
*/
static int use_sideband;
+static int check_export;
+static int strict;
static void reset_timeout(void)
{
@@ -455,7 +457,7 @@ static int get_common_commits(void)
}
}
-static void receive_needs(void)
+static char *receive_needs(void)
{
static char line[1000];
int len;
@@ -466,8 +468,10 @@ static void receive_needs(void)
len = packet_read_line(0, line, sizeof(line));
reset_timeout();
if (!len)
- return;
+ return NULL;
+ if (!strncmp("switch-repo ", line, 12))
+ return line+12;
if (strncmp("want ", line, 5) ||
get_sha1_hex(line+5, sha1_buf))
die("git-upload-pack: protocol error, "
@@ -501,7 +505,7 @@ static void receive_needs(void)
static int send_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
{
- static const char *capabilities = "multi_ack thin-pack side-band side-band-64k";
+ static const char *capabilities = "multi_ack thin-pack side-band side-band-64k switch-repo";
struct object *o = parse_object(sha1);
if (!o)
@@ -524,13 +528,60 @@ static int send_ref(const char *refname,
return 0;
}
+extern int did_read_loose_refs;
static void upload_pack(void)
{
- reset_timeout();
- head_ref(send_ref, NULL);
- for_each_ref(send_ref, NULL);
- packet_flush(1);
- receive_needs();
+ int multirepo = 0;
+
+ while (1) {
+ char *repo;
+ char cwd[PATH_MAX];
+
+ reset_timeout();
+ head_ref(send_ref, NULL);
+ for_each_ref(send_ref, NULL);
+ packet_flush(1);
+ repo = receive_needs();
+ if (!repo)
+ /* This is where we go most of the time, unless this is
+ * a multirepo fetch */
+ break;
+ multirepo++;
+
+ fprintf(stderr, "git-upload-pack: switching to repo %s\n", repo);
+
+ /* So that we still find objects of the original repository... */
+ getcwd(cwd, PATH_MAX);
+ if (strlen(cwd) < PATH_MAX - 8)
+ strcat(cwd, "/objects");
+ link_alt_odb_entry(cwd, strlen(cwd), NULL, 0, 1);
+
+ if (!enter_repo(repo, strict) || !security_repo_check(!check_export))
+ die("git-upload-pack: security violation");
+ /* This is a hack and a memory leak. If you are seeing this
+ * in a stock Git version, someone did a horrible mistake. */
+ did_read_loose_refs = 0;
+ }
+
+ if (multirepo) {
+#define ALTENV_SIZE 65536
+ /* Propagate all the repositories to the children */
+ char altenv[ALTENV_SIZE], *p = altenv;
+ struct alternate_object_database *alt;
+ strcpy(p, ALTERNATE_DB_ENVIRONMENT "=");
+ p += sizeof(ALTERNATE_DB_ENVIRONMENT);
+ for (alt = alt_odb_list; alt; alt = alt->next) {
+ strncpy(p, alt->base, alt->name - alt->base);
+ p += alt->name - alt->base;
+ if (p - altenv < ALTENV_SIZE)
+ *p++ = ':';
+ if (p - altenv >= ALTENV_SIZE)
+ die("fetching too many repositories");
+ }
+ p[-1] = '\0';
+ putenv(altenv);
+ }
+
if (want_obj.nr) {
get_common_commits();
create_pack_file();
@@ -541,7 +592,6 @@ int main(int argc, char **argv)
{
char *dir;
int i;
- int strict = 0;
for (i = 1; i < argc; i++) {
char *arg = argv[i];
@@ -556,6 +606,10 @@ int main(int argc, char **argv)
timeout = atoi(arg+10);
continue;
}
+ if (!strcmp(arg, "--check-export")) {
+ check_export = 1;
+ continue;
+ }
if (!strcmp(arg, "--")) {
i++;
break;
^ permalink raw reply related
* [RFC][PATCH] for_each_ref() returning heads in wrong order
From: Petr Baudis @ 2006-09-23 16:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: torvalds, git
Using the #next branch I've now hit a problem with git-fetch-pack
master choosing refs/bases/master (I geuss created by StGIT) instead
of refs/heads/master. The old upload-pack returned the refs in the order
heads-tags-everything_else but the new one just goes for whatever order
readdir() returns them in (modulo merging with packed refs). I actually
can't see the difference that caused this right now, though.
This is a _really ugly_ patch to fix that. I wonder if there's a more
elegant solution to this.
If you have your refs already packed, you should somehow unpack them
and then pack them again.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
I send the patch with the hope that someone will be so irritated by it
that he'll create a nicer one. ;-)
refs.c | 39 ++++++++++++++++++++++++++++++++++++---
1 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/refs.c b/refs.c
index 2cef2b4..9b3986a 100644
--- a/refs.c
+++ b/refs.c
@@ -91,7 +91,8 @@ static struct ref_list *get_packed_refs(
return refs;
}
-static struct ref_list *get_ref_dir(const char *base, struct ref_list *list)
+static struct ref_list *get_ref_dir(const char *base, struct ref_list *list,
+ char **except)
{
DIR *dir = opendir(git_path("%s", base));
@@ -121,7 +122,13 @@ static struct ref_list *get_ref_dir(cons
if (stat(git_path("%s", ref), &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- list = get_ref_dir(ref, list);
+ if (except) {
+ char **e;
+ for (e = except; *e; e++)
+ if (!strcmp(*e, ref))
+ goto nextitem;
+ }
+ list = get_ref_dir(ref, list, except);
continue;
}
if (!resolve_ref(ref, sha1, 1, &flag)) {
@@ -129,6 +136,7 @@ static struct ref_list *get_ref_dir(cons
continue;
}
list = add_ref(ref, sha1, flag, list);
+nextitem:;
}
free(ref);
closedir(dir);
@@ -142,7 +150,23 @@ static struct ref_list *get_loose_refs(v
static struct ref_list *refs = NULL;
if (!did_refs) {
- refs = get_ref_dir("refs", NULL);
+ /* We need to make sure refs/heads and refs/tags always
+ * go before everything else. */
+ char *except[] = {"refs/heads", "refs/tags", NULL};
+ struct ref_list *other_refs = NULL, *r;
+
+ refs = get_ref_dir("refs/heads", NULL, NULL);
+ refs = get_ref_dir("refs/tags", refs, NULL);
+
+ other_refs = get_ref_dir("refs", NULL, except);
+ if (refs) {
+ for (r = refs; r->next; r = r->next)
+ ;
+ r->next = other_refs;
+ } else {
+ refs = other_refs;
+ }
+
did_refs = 1;
}
return refs;
@@ -298,10 +322,19 @@ static int do_for_each_ref(const char *b
while (packed && loose) {
struct ref_list *entry;
int cmp = strcmp(packed->name, loose->name);
+ int packed_is_ht, loose_is_ht;
if (!cmp) {
packed = packed->next;
continue;
}
+ /* We need to make sure refs/heads and refs/tags always
+ * go before everything else. */
+ packed_is_ht = !strncmp(packed->name, "refs/heads", 10)
+ || !strncmp(packed->name, "refs/tags", 9);
+ loose_is_ht = !strncmp(loose->name, "refs/heads", 10)
+ || !strncmp(loose->name, "refs/tags", 9);
+ if (packed_is_ht != loose_is_ht)
+ cmp = loose_is_ht - packed_is_ht;
if (cmp > 0) {
entry = loose;
loose = loose->next;
^ permalink raw reply related
* Re: git commands that only work correctly at top directory
From: Petr Baudis @ 2006-09-23 15:16 UTC (permalink / raw)
To: git
In-Reply-To: <20060922112615.GB10124@moooo.ath.cx>
Dear diary, on Fri, Sep 22, 2006 at 01:26:15PM CEST, I got a letter
where Matthias Lederhofer <matled@gmx.net> said that...
> repack/bisect/reset and some other commands make only sense from the
> toplevel directory but anyway I would allow them to be run in a
> subdirectory and change up to the topdirectory (like git checkout for
> branch switching). Is there any good reason not to do this? I found
> it often annoying to go down to the toplevel directory/get a new shell
> just to reset to HEAD~1.
Probably not for repack, but in case of bisect and especially reset it
would be reasonable to expect that it will touch just the subdirectory
and in case of git reset --hard that could be deadly.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* [PATCH 2/2] Rename builtin-zip-tree.c to archive-zip.c
From: Rene Scharfe @ 2006-09-23 15:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Franck Bui-Huu, Git Mailing List
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
Makefile | 5 ++---
builtin-zip-tree.c => archive-zip.c | 0
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index 8467447..739d7e3 100644
--- a/Makefile
+++ b/Makefile
@@ -254,7 +254,7 @@ LIB_OBJS = \
fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
write_or_die.o trace.o list-objects.o \
alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
- color.o wt-status.o
+ color.o wt-status.o archive-zip.o
BUILTIN_OBJS = \
builtin-add.o \
@@ -300,8 +300,7 @@ BUILTIN_OBJS = \
builtin-upload-archive.o \
builtin-upload-tar.o \
builtin-verify-pack.o \
- builtin-write-tree.o \
- builtin-zip-tree.o
+ builtin-write-tree.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
diff --git a/builtin-zip-tree.c b/archive-zip.c
similarity index 100%
rename from builtin-zip-tree.c
rename to archive-zip.c
^ permalink raw reply related
* [PATCH 1/2] Remove git-zip-tree
From: Rene Scharfe @ 2006-09-23 15:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Franck Bui-Huu, Git Mailing List
git-zip-tree can be safely removed because it was never part of a formal
release. This patch makes 'git-archive --format=zip' the one and only git
ZIP file creation command.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
Documentation/git-zip-tree.txt | 67 ----------------------------------------
.gitignore | 1 -
builtin-zip-tree.c | 65 --------------------------------------
builtin.h | 1 -
git.c | 1 -
5 files changed, 0 insertions(+), 135 deletions(-)
diff --git a/Documentation/git-zip-tree.txt b/Documentation/git-zip-tree.txt
deleted file mode 100644
index 2e9d981..0000000
--- a/Documentation/git-zip-tree.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-git-zip-tree(1)
-===============
-
-NAME
-----
-git-zip-tree - Creates a ZIP archive of the files in the named tree
-
-
-SYNOPSIS
---------
-'git-zip-tree' [-0|...|-9] <tree-ish> [ <base> ]
-
-DESCRIPTION
------------
-Creates a ZIP archive containing the tree structure for the named tree.
-When <base> is specified it is added as a leading path to the files in the
-generated ZIP archive.
-
-git-zip-tree behaves differently when given a tree ID versus when given
-a commit ID or tag ID. In the first case the current time is used as
-modification time of each file in the archive. In the latter case the
-commit time as recorded in the referenced commit object is used instead.
-Additionally the commit ID is stored as an archive comment.
-
-Currently git-zip-tree can handle only files and directories, symbolic
-links are not supported.
-
-OPTIONS
--------
-
--0::
- Store the files instead of deflating them.
-
--9::
- Highest and slowest compression level. You can specify any
- number from 1 to 9 to adjust compression speed and ratio.
-
-<tree-ish>::
- The tree or commit to produce ZIP archive for. If it is
- the object name of a commit object.
-
-<base>::
- Leading path to the files in the resulting ZIP archive.
-
-EXAMPLES
---------
-git zip-tree v1.4.0 git-1.4.0 >git-1.4.0.zip::
-
- Create a ZIP file for v1.4.0 release.
-
-git zip-tree HEAD:Documentation/ git-docs >docs.zip::
-
- Put everything in the current head's Documentation/ directory
- into 'docs.zip', with the prefix 'git-docs/'.
-
-Author
-------
-Written by Rene Scharfe.
-
-Documentation
---------------
-Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.
-
-GIT
----
-Part of the gitlink:git[7] suite
-
diff --git a/.gitignore b/.gitignore
index a3d9c7a..3ca66e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -128,7 +128,6 @@ git-verify-pack
git-verify-tag
git-whatchanged
git-write-tree
-git-zip-tree
git-core-*/?*
gitweb/gitweb.cgi
test-date
diff --git a/builtin-zip-tree.c b/builtin-zip-tree.c
index 52d4b7a..3ffdad6 100644
--- a/builtin-zip-tree.c
+++ b/builtin-zip-tree.c
@@ -10,9 +10,6 @@ #include "quote.h"
#include "builtin.h"
#include "archive.h"
-static const char zip_tree_usage[] =
-"git-zip-tree [-0|...|-9] <tree-ish> [ <base> ]";
-
static int verbose;
static int zip_date;
static int zip_time;
@@ -294,68 +291,6 @@ static void dos_time(time_t *time, int *
*dos_time = t->tm_sec / 2 + t->tm_min * 32 + t->tm_hour * 2048;
}
-int cmd_zip_tree(int argc, const char **argv, const char *prefix)
-{
- unsigned char sha1[20];
- struct tree *tree;
- struct commit *commit;
- time_t archive_time;
- char *base;
- int baselen;
-
- git_config(git_default_config);
-
- if (argc > 1 && argv[1][0] == '-') {
- if (isdigit(argv[1][1]) && argv[1][2] == '\0') {
- zlib_compression_level = argv[1][1] - '0';
- argc--;
- argv++;
- }
- }
-
- switch (argc) {
- case 3:
- base = xstrdup(argv[2]);
- baselen = strlen(base);
- break;
- case 2:
- base = xstrdup("");
- baselen = 0;
- break;
- default:
- usage(zip_tree_usage);
- }
-
- if (get_sha1(argv[1], sha1))
- die("Not a valid object name %s", argv[1]);
-
- commit = lookup_commit_reference_gently(sha1, 1);
- archive_time = commit ? commit->date : time(NULL);
- dos_time(&archive_time, &zip_date, &zip_time);
-
- zip_dir = xmalloc(ZIP_DIRECTORY_MIN_SIZE);
- zip_dir_size = ZIP_DIRECTORY_MIN_SIZE;
-
- tree = parse_tree_indirect(sha1);
- if (!tree)
- die("not a tree object");
-
- if (baselen > 0) {
- write_zip_entry(tree->object.sha1, "", 0, base, 040777, 0);
- base = xrealloc(base, baselen + 1);
- base[baselen] = '/';
- baselen++;
- base[baselen] = '\0';
- }
- read_tree_recursive(tree, base, baselen, 0, NULL, write_zip_entry);
- write_zip_trailer(commit ? commit->object.sha1 : NULL);
-
- free(zip_dir);
- free(base);
-
- return 0;
-}
-
int write_zip_archive(struct archiver_args *args)
{
int plen = strlen(args->base);
diff --git a/builtin.h b/builtin.h
index ccade94..f9fa9ff 100644
--- a/builtin.h
+++ b/builtin.h
@@ -53,7 +53,6 @@ extern int cmd_show(int argc, const char
extern int cmd_stripspace(int argc, const char **argv, const char *prefix);
extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);
extern int cmd_tar_tree(int argc, const char **argv, const char *prefix);
-extern int cmd_zip_tree(int argc, const char **argv, const char *prefix);
extern int cmd_unpack_objects(int argc, const char **argv, const char *prefix);
extern int cmd_update_index(int argc, const char **argv, const char *prefix);
extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index 44ab0de..1686220 100644
--- a/git.c
+++ b/git.c
@@ -259,7 +259,6 @@ static void handle_internal_command(int
{ "stripspace", cmd_stripspace },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tar-tree", cmd_tar_tree, RUN_SETUP },
- { "zip-tree", cmd_zip_tree, RUN_SETUP },
{ "unpack-objects", cmd_unpack_objects, RUN_SETUP },
{ "update-index", cmd_update_index, RUN_SETUP },
{ "update-ref", cmd_update_ref, RUN_SETUP },
^ permalink raw reply related
* Re: [PATCH] gitweb: Even more support for PATH_INFO based URLs
From: Jakub Narebski @ 2006-09-23 14:55 UTC (permalink / raw)
To: Petr Baudis, git
In-Reply-To: <20060923142941.GL8259@pasky.or.cz>
Petr Baudis wrote:
> Dear diary, on Wed, Sep 20, 2006 at 12:49:51AM CEST, I got a letter
> where Jakub Narebski <jnareb@gmail.com> said that...
> > Now the following types of path based URLs are supported:
> >
> > * project overview (summary) page of project
> > * project/branch shortlog of branch
> > * project/branch:file file in branch, blob_plain view
> > * project/branch:dir/ directory listing of dir in branch, tree view
> >
> > The following shortcuts works (see explanation below):
> >
> > * project/branch: directory listing of branch, main tree view
> > * project/:file file in HEAD (raw)
> > * project/:dir/ directory listing of dir in HEAD
> > * project/: directory listing of project's HEAD
>
> I haven't followed this stuff carefully but just to confirm, there is
> currently no way to persuade gitweb to actually produce such links,
> right?
>
> I like pathinfo and would like to use it for repo.or.cz's gitweb.
Well, all inner links go through href() subroutine, so this is where
you would want to make changes. Having project in pathinfo would be easy,
having branch/ref harder because it might be in hash, or in hash_base
parameter.
Perhaps we should use
my $path_info = $ENV{MOD_PERL} ? $r->path_info() : $ENV{PATH_INFO};
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH] gitweb: Even more support for PATH_INFO based URLs
From: Petr Baudis @ 2006-09-23 14:29 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, Martin Waitz, Matthias Lederhofer
In-Reply-To: <200609200049.52036.jnareb@gmail.com>
Hi,
Dear diary, on Wed, Sep 20, 2006 at 12:49:51AM CEST, I got a letter
where Jakub Narebski <jnareb@gmail.com> said that...
> Now the following types of path based URLs are supported:
>
> * project overview (summary) page of project
> * project/branch shortlog of branch
> * project/branch:file file in branch, blob_plain view
> * project/branch:dir/ directory listing of dir in branch, tree view
>
> The following shortcuts works (see explanation below):
>
> * project/branch: directory listing of branch, main tree view
> * project/:file file in HEAD (raw)
> * project/:dir/ directory listing of dir in HEAD
> * project/: directory listing of project's HEAD
I haven't followed this stuff carefully but just to confirm, there is
currently no way to persuade gitweb to actually produce such links,
right?
I like pathinfo and would like to use it for repo.or.cz's gitweb.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ permalink raw reply
* Re: Git user survey and `git pull`
From: Johannes Schindelin @ 2006-09-23 14:12 UTC (permalink / raw)
To: Matthias Urlichs; +Cc: git
In-Reply-To: <ef1j6j$8sn$1@sea.gmane.org>
Hi,
On Fri, 22 Sep 2006, Matthias Urlichs wrote:
> For what it's worth, I'm in favor of renaming the things.
>
> On Thu, 21 Sep 2006 12:24:01 -0400, Shawn Pearce wrote:
>
> > Current Shoulda Been
> > --------------- ----------------
> > git-push git-push
> > git-fetch git-pull
> > git-pull . foo git-merge foo
> > git-pull git-pull --merge
> > git-merge git-merge-driver
> >
> The new programs can (for the most part) recognize when they're called with
> "old" semantics, and spit out a warning.
Now, that only introduces more confusion!
If there is another tool rename, better choose names which are virgins.
Besides, I am still not convinced that the rename is necessary. Granted,
some new users might get confused with the current naming, but what about
those who are not? They would be confused by the new naming.
And if you want unambiguous names, and even succeed in choosing sensible
ones, you can make them hardwired aliases, and old habits don't have to
die.
Ciao,
Dscho
^ permalink raw reply
* Re: [RFC/PATCH] gitweb: Add committags support
From: Petr Baudis @ 2006-09-23 14:05 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git
In-Reply-To: <200609231533.02455.jnareb@gmail.com>
Dear diary, on Sat, Sep 23, 2006 at 03:33:01PM CEST, I got a letter
where Jakub Narebski <jnareb@gmail.com> said that...
> Petr Baudis wrote:
>
> > Dear diary, on Sat, Sep 23, 2006 at 10:34:49AM CEST, I got a letter
> > where Jakub Narebski <jnareb@gmail.com> said that...
>
> > Also, there is a fundamental limitation for the multi-word patterns that
> > they won't work if the line wraps at that point in the log message. This
> > will likely be a problem especially for the msgids, because those are
> > very long and are very likely to cause a linewrap immediately before.
>
> We do not wrap log messages in gitweb. So the problem is only when
> commit message is wrongly wrapped itself (pre imples nowrap).
The commit message is not "wrongly" wrapped but just wrapped to fit into
72 or whatever columns. It would be silly to mandate users to use msg-id: <200609231533.02455.jnareb@gmail.com>
with the message id stretching far away just for the sake of some
gitweb limitations when having the message wrapped such as msg-id:
<200609231533.02455.jnareb@gmail.com> looks much more reasonable.
> >> > > +);
> >> > ..snip..
> >> > > +sub quote_msgid_gmane {
> >> > > + my $msgid = shift || return;
> >> > > +
> >> > > + return '<'.(quotemeta $msgid).'>';
> >> > > +}
> >> >
> >> > <> should be HTML-escaped (unless CGI::a() does that).
> >>
> >> CGI::a() probably does that. But true, "<" and ">" should be "params quoted":
> >>
> >> return '%3c' . (quotemeta $msgid) . '%3e';
> >
> > Ah, silly me, I didn't notice that it goes into the URL.
>
> Should it be "params quoted" or not? What are valid characters
> in message-id? (And in which RFC it is defined?)
RFC2822. Unfortunately there can be all kind of crap inside if you put
it inside quotes, so yes, it should.
What a pity that (apparently) noone supports RFC2392.
> >> (Quotemeta is because Message-Id contains '@').
> >
> > Hmm, and at which point would that be eaten?
>
> In the substitution phase... but perhaps I was to defensive.
> s/$from/$to/g where $to can have '@'.
$ perl -le 'my $x="a\@bc"; my $y="@"; $x =~ s/$y/$y.$y/g; print $x;'
a@.@bc
You probably should regexp-quote $from if you don't yet, though,
although a misbehaviour from that side is not very probable.
> >> > Subjects are often clickable and we don't want links in those.
> >>
> >> The extra code with $a_attr is to have links within links. It works
> >> quite well, I'd say. The subject link is broken, and the committag
> >> link is inserted in the break (gitweb-xmms2 committag code did the same,
> >> but did not preserved all the subject link attributes, like title or class,
> >> only the target of the link).
> >>
> >> The result is somethink like:
> >>
> >> <a href="..." class="subject" ...>Fix </a><a href="...=137">BUG(137)</a><a href="..." class="subject" ...>: ...</a>
> >
> > I don't think this is good idea though - if I'm clicking at links, I
> > don't want to have to carefully watch where that bit of the link leads.
> > IMHO this would be just annoying.
>
> The committag links within subject link are clearly visually distinguished:
> first they have default link color (blue for not visited, dark red for
> visited links), second they are not bold width (as opposed to gitweb-xmms2,
> where bold font was due to <b>...</b> element and not CSS styling
> of a.subject).
Ok, in that case it's better though I'm still feeling somewhat
uncomfortable about it. What if the _whole_ subject is just "Bug 1324"?
I can click the 'commit' link instead but it throws exception in my
brain I need to handle and I need to move my mouse around.
> > I meant that we should consider substituting the committags in those as
> > well.
>
> Ahh... For tags I guess it is a good idea (especially that I think that
> fixes for bugtracker tracked bugs and feature request should be marked by tags,
> e.g. b/<bugid>, to be used to link to commit/change/patch from bugtracker.
For blobs, the point is mainly comments, those can contain all kinds of
stuff.
> By the way, should we use some color for PGP signature block in signed tags?
Sounds like a good idea.
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)
^ 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