Git development
 help / color / mirror / Atom feed
* Re: [RFD] consider "git" wrapper semi-Porcelain
From: Linus Torvalds @ 2005-06-26  1:21 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy88yvsjl.fsf_-_@assigned-by-dhcp.cox.net>



On Sat, 25 Jun 2005, Junio C Hamano wrote:
> 
> I would propose the following, preferably before we go 1.0:

Agreed on all counts.

		Linus

^ permalink raw reply

* [ANNOUNCE] gitfs pre-release 0.01
From: Mitchell Blank Jr @ 2005-06-26  4:24 UTC (permalink / raw)
  To: Git Mailing List

GITFS pre-release version 0.01

gitfs is a FUSE-based filesystem for working with source trees stored in
git repositories.  Currently only very basic functionality is implemented
but I'm hoping to expand it into a useful tool for managing many builds
and patches.

OVERALL PLAN
======= ====

Many years ago I had an idea for a filesystem that would make importing
patches and spinning kernel builds far more efficient.  The basic idea was:

  1. Store the unchanged part of the source tree in a shared repository;
     only keep a separate copy of the files and directories that have
     changed.  This would be similar to doing hardlinked source tree copies
     but be even faster -- checking out a new tree would be as quick as
     mkdir'ing a new empty directory.

  2. On top of this, implement a very-fast "diff" operator that only worked
     on changed files

  3. Have ccache-style compiler caching built in.  The filesystem could
     (using some wrapper programs) watch every file read and written to
     by a command like "gcc".  Since it knows what versions of those files
     were read at that time it can know very quickly if any of them changed.

     This saves the "gcc -E" step that ccache must do to determine that it
     can use the cached .o result and should be quite a bit faster.

So basically common operations such as "compile a test kernel with this
fix" and "produce a well-formed patch describing how my current tree
diverges from mainline" become very fast.

Several times I started to implement this idea but every time I got bogged
down in the details of making kernel parts of the file system and such work.
However, two things changed recently:

  1. git came along; I realized that I could use it for the backing data
     store.  Since the linux kernel is already published in git format
     this is especially handy.  Leveraging the existing git code and
     design has sped this up immeasurably.

  2. FUSE (filesystem in userspace) has become more widely available --
     it hasn't make it to mainline yet but it is in the -mm series kernels.
     This made getting started on actual implementation a lot easier.
     Writing a userspace filesystem on top of FUSE is really a joy.

I'm currently calling this project "gitfs" although perhaps that is a
bit of a misnomer since I am _absolutely_not_ trying to implement the
full SCM workflow as a filesystem.  In fact we present hardly any git
metadata like commit messages at all.  Also, I operate on the underlying
objects directly - the index file is never touched.

However, I decided to stick with the "gitfs" name for now -- I'm hoping that
this project can grow to become a useful compliment to the git workflow.
I'm not adverse to giving it a different name if it's an issue, though.

CURRENT STATE
======= =====

This is an early pre-release that only demonstrates the most basic of
functionality -- read-only access to the existing tags and objects in
the git repository.  Still, it's already a somewhat handy tool which is
why I'm announcing it now.

In addition to the missing functionality, currently there is a lot of
performance work to do -- I've been working on getting it functionally
correct first.  Specific performance work I'm planing includes:

  1. Every time we touch a directory (whether lookup or readdir) we parse
     the git tree object into a memory structure which then immediately gets
     thrown away.  There is some infrastructure for caching these objects
     in memory which will solve the problem, but it's not completed yet.

  2. On a related note, I need to do some data structure work -- in some
     places I'm using simple linked lists where I really should be using
     B-tree's or something.  I actually have a lot of this work done already
     but I need to do some heavy testing before I integrate that into my
     tree.

  3. Since we cache the uncompressed file data our read/write operations
     always go straight through to the underlying files.  A large performance
     boost would be available if at open()-time we could tell the kernel
     "here's the file descriptor I opened for you, do I/O to that"  That
     way we could avoid the need for all data to make two user/kernel
     transitions.  However, this would require some extensive work to
     FUSE to implement.

  4. We are currently single threaded; I eventually am planning on adding
     service threads for handling CPU bound tasks.  I want to keep the
     normal filesystem operations single-threaded (they're generally just
     walking in-memory structures so they're fast anyway), but things like
     uncompressing a git object should really be done in separate thread
     so they won't block other filesystem operations.

Finally, since I'm still working on finishing the infrastructure work, please
just consider this a "preview release"  Feel free to play with it, look at
the code, poke it with sticks, etc.  However, the code base is still rapidly
evolving so I probably won't be able to integrate any non-trivial patches yet.
The code also needs things like more comments and clear error messages.

BUILDING GITFS
======== =====

  Gitfs can currently be obtained at:
	http://www.sfgoth.com/~mitch/linux/gitfs/

  Please refer to the included INSTALL file for directions on compiling
  the gitfs binary.

RUNNING GITFS
======= =====

  MOUNT:
    gitfs [-d] [-O object_cache_dir] <gitdir> <mntpoint>
  UMOUNT:
    gitfs -u [-d] <dir>

  Options:

    -d -- debugging mode; we run in the foreground and print very verbose
          messages about what is going on (mostly courtesy of FUSE)

    -O -- specify an object cache directory.  For fast performance we always
	  store the result of decompressing a git "blob" object in a file.
	  This directory is where the decompressed objects live.

    	  This currently defaults to "/tmp/gitfs/ocache"  DO NOT make this
	  the same as your ".git/objects" directory or things will probably
	  become horribly broken!

	  Currently gitfs never removes anything from the ocache so it
	  can grow quite large.  However it's safe to prune files from it
	  (or even blow away the entire tree) while gitfs is running.

Under normal operation gitfs would run in the background until you unmount
it with "gitfs -u"  *However*, we currently always run in "debug" mode so the
gitfs program runs in the foreground.  To shut down you just have to send
it a ctrl-C and it should shut down cleanly.  For now you should only have
to use "gitfs -u" if something goes wrong and it crashes.

EXAMPLE SESSION
======= =======

  $ gitfs ~/git/linux-2.6 /tmp/fuse

  [then in another window]
  $ cd /tmp/fuse
  $ ls -l
  total 0
  dr-xr-xr-x  2 mitch mitch 0 Apr 20 16:38 HEADS
  dr-xr-xr-x  2 mitch mitch 0 May 24 20:32 TAGS
  $ ls -l TAGS
  total 0
  lrwxrwxrwx  1 mitch mitch 43 May  4 16:51 v2.6.11 -> ../5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c
  lrwxrwxrwx  1 mitch mitch 43 May  4 16:51 v2.6.11-tree -> ../5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c
  lrwxrwxrwx  1 mitch mitch 43 May  1 17:16 v2.6.12-rc2 -> ../9e734775f7c22d2f89943ad6c745571f1930105f
  lrwxrwxrwx  1 mitch mitch 43 May  1 17:15 v2.6.12-rc3 -> ../0397236d43e48e821cce5bbe6a80a1a56bb7cc3a
  lrwxrwxrwx  1 mitch mitch 43 May  6 22:22 v2.6.12-rc4 -> ../ebb5573ea8beaf000d4833735f3e53acb9af844c
  lrwxrwxrwx  1 mitch mitch 43 May 24 20:32 v2.6.12-rc5 -> ../06f6d9e2f140466eeb41e494e14167f90210f89d
  $ cd TAGS/v2.6.11
  $ ls
  arch     Documentation  init    MAINTAINERS  README          sound
  COPYING  drivers        ipc     Makefile     REPORTING-BUGS  usr
  CREDITS  fs             kernel  mm           scripts
  crypto   include        lib     net          security
  $ pwd
  /tmp/fuse/TAGS/v2.6.11
  $ /bin/pwd
  /var/tmp/fuse/5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c
  $ ls -l /tmp/fuse
  total 0
  dr-xr-xr-x  18 mitch mitch 352 May  4 16:50 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c
  dr-xr-xr-x   2 mitch mitch   0 Apr 20 16:38 HEADS
  dr-xr-xr-x   2 mitch mitch   0 May 24 20:32 TAGS

^ permalink raw reply

* Re: [Cogito] less verbose cg-clone/cg-update?
From: Frank Sorenson @ 2005-06-26  6:19 UTC (permalink / raw)
  To: Markus Dahms; +Cc: git, Petr Baudis
In-Reply-To: <pan.2005.06.24.06.46.32.339572@automagically.de>

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Markus Dahms wrote:
> Hi there,
> 
> as a person just following the development process of Linux/GIT/etc.
> I'm normally not interested in SHA-1 sums on updating my local tree.
> IMHO the default output should be less verbose (like in most VCSs),
> especially in file changes the type of change (N/M/...) and the
> file name may be enough.
> Given an option (e.g. "-v") there could be a lot more...
> 
> If there's no time, I'd do the patch...
> 
> Markus
> 
> P.S.: I didn't really look at the source, maybe it's a git not
>       a cg-* change...

Here is a patch that implements a cogito-based "quiet" output option
(-q) for cg-pull.  This could easily be inverted to default to quiet
and allow the verbose option instead.  Also, with the option in there,
it wouldn't be hard to quiet up other portions of cg-pull.

Signed-off-by: Frank Sorenson <frank@tuxrocks.com>

diff --git a/cg-pull b/cg-pull
- --- a/cg-pull
+++ b/cg-pull
@@ -11,15 +11,21 @@
 # -------
 # -f::
 #	Force the complete pull even if the heads are the same.
+#
+# -q::
+#	Display quieter output
 
- -USAGE="cg-pull [-f] [BRANCH_NAME]"
+USAGE="cg-pull [-f] [-q] [BRANCH_NAME]"
 
 . ${COGITO_LIB}cg-Xlib
 
 force=
+quiet=
 while optparse; do
 	if optparse -f; then
 		force=1
+	elif optparse -q; then
+		quiet=1
 	else
 		optfail
 	fi
@@ -309,8 +315,11 @@ if [ ! "$orig_head" ]; then
 
 elif [ "$orig_head" != "$new_head" ]; then
 	echo "Tree change: $orig_head:$new_head"
- -	git-diff-tree -r $(tree-id $orig_head) $(tree-id $new_head)
- -
+	if [ "$quiet" ] ; then
+		git-diff-tree -r $(tree-id $orig_head) $(tree-id $new_head) | awk '{ print $5"\t"$6 }'
+	else
+		git-diff-tree -r $(tree-id $orig_head) $(tree-id $new_head)
+	fi
 else
 	echo "Up to date."
 	exit


Frank
- -- 
Frank Sorenson - KD7TZK
Systems Manager, Computer Science Department
Brigham Young University
frank@tuxrocks.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCvkj8aI0dwg4A47wRAuOvAKCllJCjte1ITkPCtKOfAqd8zY1fzgCgscg2
EZ5jKuLBFF+0lb5ZoOd6bHE=
=YC02
-----END PGP SIGNATURE-----

^ permalink raw reply

* Re: [RFD] consider "git" wrapper semi-Porcelain
From: Junio C Hamano @ 2005-06-26 12:02 UTC (permalink / raw)
  To: git; +Cc: Linus Torvalds
In-Reply-To: <Pine.LNX.4.58.0506251821050.19755@ppc970.osdl.org>

>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:

LT> On Sat, 25 Jun 2005, Junio C Hamano wrote:
>> 
>> I would propose the following, preferably before we go 1.0:

LT> Agreed on all counts.

With holy Penguin pee blessings, I would send in a "flag day"
patch sometime before July 4th weekend that:

 - renames most of the git-*-script to git-*-cmd;
 - renames git-whatchanged to git-whatchanged-cmd;
 - renames two misnamed git-*-script to git-*-helper

without any backward compatibility warts.

Unless people object and propose good transition plans, that
is.

This message is for people who uses bare GIT and who writes
Porcelain.  Please consider yourselves warned ;-).


^ permalink raw reply

* Re: [RFD] consider "git" wrapper semi-Porcelain
From: Martijn Kuipers @ 2005-06-26 12:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Linus Torvalds
In-Reply-To: <7voe9ts4vt.fsf@assigned-by-dhcp.cox.net>

Hi,

Junio C Hamano wrote:

> - renames most of the git-*-script to git-*-cmd;

Wouldn't this ruin the nice tab-completion? git-plumbing and 
git-porcelain will only be distinctable from their last part.
Maybe I understood wrong, but if people are supposed to "just" use 
git-porcelain for every day use, then probably it would make more sense 
to rename to gitp-* for porcelain, as the tab-completion would work from 
the first word , which would be less confusing for us mere users (yes, 
any alternative first word would work).

Kind regards,
Martijn


^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Linus Torvalds @ 2005-06-26 16:41 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David S. Miller, Git Mailing List, Nicolas Pitre, Chris Mason
In-Reply-To: <Pine.LNX.4.58.0506242257450.11175@ppc970.osdl.org>



On Fri, 24 Jun 2005, Linus Torvalds wrote:
> 
> yeah, it clearly needs some refining to be useful, but I think you can
> kind of see how it would work.

Ok, here's how it works.

 - Pick a starting commit (or a hundred)

 - Pick an ending commit (or a hundred)

 - generate the list of objects in between them

	git-rev-list --object end ^start > object-list

 - Pack that list of objects into an "object pack":

	git-pack-objects out < object-list

   (This actually generates two files: "out.idx" is the index file, 
   "out.pack" is the data file, but I'll make it concatenate the two at 
   some point)

 - move the pack-files over somewhere else

 - unpack them

	git-unpack-objects out

and you're done.

Now, the reason I use "pack" and "unpack" instead of just "tar" to
transport the objects is that this allows me to do a fairly efficient
packing. I wanted these pack-files to be independent (ie they do _not_
depend on any objects outside of the pack-file), but within the objects
described in the pack I cna do delta-compression.

Now, that doesn't much help for small updates (where the objects are just 
unrelated and have no deltas), but it helps increasingly for big ones. The 
biggest one obviously being the whole path from the start to the HEAD..

For example, the "du -sh .git/objects" for the git project itself is 17MB 
for me, and I can do:

	torvalds@ppc970:~/git> du -sh .git/objects 
	17M     .git/objects

	torvalds@ppc970:~/git> time git-rev-list --objects HEAD | git-pack-objects out
	Packing 3656 objects

	real    0m3.779s
	user    0m3.169s
	sys     0m0.602s

	torvalds@ppc970:~/git> ls -lh out.*
	-rw-rw-r--  1 torvalds torvalds  87K Jun 26 09:12 out.idx
	-rw-rw-r--  1 torvalds torvalds 2.0M Jun 26 09:12 out.pack

ie it packs down to a nice 2MB pack-file with a small index. Move that
over to somewhere else, and unpack it, and you'll get all the regular
objects (it doesn't move tags and refs over, you'll have to do that
outside of the packing).

Now, you can trade off some packing time to get a better pack:

	torvalds@ppc970:~/git> time git-rev-list --objects HEAD | git-pack-objects --window=100 out
	Packing 3656 objects
	
	real    0m11.953s
	user    0m11.294s
	sys     0m0.663s

	torvalds@ppc970:~/git> ls -lh out.*
	-rw-rw-r--  1 torvalds torvalds  87K Jun 26 09:14 out.idx
	-rw-rw-r--  1 torvalds torvalds 1.6M Jun 26 09:14 out.pack

and if you want to allow deep delta chains (the default delta depth
limiting is 10), you can get even better results:

	torvalds@ppc970:~/git> time git-rev-list --objects HEAD | git-pack-objects --window=100 --depth=100 out
	Packing 3656 objects
	
	real    0m12.374s
	user    0m11.704s
	sys     0m0.659s

	torvalds@ppc970:~/git> ls -lh out.*
	-rw-rw-r--  1 torvalds torvalds  87K Jun 26 09:16 out.idx
	-rw-rw-r--  1 torvalds torvalds 1.3M Jun 26 09:16 out.pack

but then unpacking will slightly heavier.

(Doing the same for the kernel is obviously much more expensive just
because the kernel is so much bigger. A big delta discovery window like
100 takes about fifteen minutes to pack on my machine, but gets the
current kernel archive down to 70MB or so. That's ok for a monthly "pack
all the objects" to keep size requirements down, but you clearly don't
want to do this all the time ;).

Now, perhaps the more interesting part is that I also designed the pack
format so that it should be a good "history" format, not just a way to
move objects from one place to the other. Ie if you worry about diskspace,
you can pack everything up to the now into one big pack, and then remove
the original objects.

Don't do that yet, btw - I haven't actually written the code to read stuff
out of packs if we don't find it in the object directory yet, but the
layout is such that it should be straightforward and pretty efficient (but
there a deep delta chain obviously _will_ cause a performance hit).

I actually like this approach better than having delta-objects in the
filesystem. Partly because the pack-file is self-contained, partly because
it also solves the fs blocking issue, yet is still efficient to look up
the results without having hardlinks etc to duplicate objects virtually.  
And when you do the packing by hand as an "archival" mechanism, it also
doesn't have any of the downsides that Chris' packing approach had.

Nico? Chris? Interested in giving it a look? It's kind of a combination of 
your things, generalized and then made to have fast lookup with the index.

Fast lookup doesn't matter for a normal unpack, of course, and if I just
always wanted to unpack all the objects (ie just an object transfer
mechanism) I'd have made the index be a toposort of the objects. But
because I wanted to be able to use it as an archival format, I needed it
to be "random-access" by object name. So the index is in fact a binary
tree (well, sorted array, so the lookup degenerates into a binary search)
with a top-level index splitting up the contents based on the first byte
(the same way the filesystem layout does).

		Linus

^ permalink raw reply

* [PATCH] Add git-relink-script to fix up missing hardlinks
From: Ryan Anderson @ 2005-06-26 18:15 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git, Junio C Hamano


Add git-relink-script

This will scan 2 or more object repositories and look for common objects, check
if they are hardlinked, and replace one with a hardlink to the other if not.

This version warns when skipping files because of size differences, and
handle more than 2 repositories automatically.

Signed-off-by: Ryan Anderson <ryan@michonline.com>

diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ SCRIPTS=git git-apply-patch-script git-m
 	git-deltafy-script git-fetch-script git-status-script git-commit-script \
 	git-log-script git-shortlog git-cvsimport-script git-diff-script \
 	git-reset-script git-add-script git-checkout-script git-clone-script \
-	gitk git-cherry git-rebase-script
+	gitk git-cherry git-rebase-script git-relink-script
 
 PROG=   git-update-cache git-diff-files git-init-db git-write-tree \
 	git-read-tree git-commit-tree git-cat-file git-fsck-cache \
diff --git a/git-relink-script b/git-relink-script
new file mode 100644
--- /dev/null
+++ b/git-relink-script
@@ -0,0 +1,173 @@
+#!/usr/bin/env perl
+# Copyright 2005, Ryan Anderson <ryan@michonline.com>
+# Distribution permitted under the GPL v2, as distributed
+# by the Free Software Foundation.
+# Later versions of the GPL at the discretion of Linus Torvalds
+#
+# Scan two git object-trees, and hardlink any common objects between them.
+
+use 5.006;
+use strict;
+use warnings;
+use Getopt::Long;
+
+sub get_canonical_form($);
+sub do_scan_directory($$$);
+sub compare_two_files($$);
+sub usage();
+sub link_two_files($$);
+
+# stats
+my $total_linked = 0;
+my $total_already = 0;
+my ($linked,$already);
+
+my $fail_on_different_sizes = 0;
+my $help = 0;
+GetOptions("safe" => \$fail_on_different_sizes,
+	   "help" => \$help);
+
+usage() if $help;
+
+my (@dirs) = @ARGV;
+
+usage() if (!defined $dirs[0] || !defined $dirs[1]);
+
+$_ = get_canonical_form($_) foreach (@dirs);
+
+my $master_dir = pop @dirs;
+
+opendir(D,$master_dir . "objects/")
+	or die "Failed to open $master_dir/objects/ : $!";
+
+my @hashdirs = grep !/^\.{1,2}$/, readdir(D);
+
+foreach my $repo (@dirs) {
+	$linked = 0;
+	$already = 0;
+	printf("Searching '%s' and '%s' for common objects and hardlinking them...\n",
+		$master_dir,$repo);
+
+	foreach my $hashdir (@hashdirs) {
+		do_scan_directory($master_dir, $hashdir, $repo);
+	}
+
+	printf("Linked %d files, %d were already linked.\n",$linked, $already);
+
+	$total_linked += $linked;
+	$total_already += $already;
+}
+
+printf("Totals: Linked %d files, %d were already linked.\n",
+	$total_linked, $total_already);
+
+
+sub do_scan_directory($$$) {
+	my ($srcdir, $subdir, $dstdir) = @_;
+
+	my $sfulldir = sprintf("%sobjects/%s/",$srcdir,$subdir);
+	my $dfulldir = sprintf("%sobjects/%s/",$dstdir,$subdir);
+
+	opendir(S,$sfulldir)
+		or die "Failed to opendir $sfulldir: $!";
+
+	foreach my $file (grep(!/\.{1,2}$/, readdir(S))) {
+		my $sfilename = $sfulldir . $file;
+		my $dfilename = $dfulldir . $file;
+
+		compare_two_files($sfilename,$dfilename);
+
+	}
+	closedir(S);
+}
+
+sub compare_two_files($$) {
+	my ($sfilename, $dfilename) = @_;
+
+	# Perl's stat returns relevant information as follows:
+	# 0 = dev number
+	# 1 = inode number
+	# 7 = size
+	my @sstatinfo = stat($sfilename);
+	my @dstatinfo = stat($dfilename);
+
+	if (@sstatinfo == 0 && @dstatinfo == 0) {
+		die sprintf("Stat of both %s and %s failed: %s\n",$sfilename, $dfilename, $!);
+
+	} elsif (@dstatinfo == 0) {
+		return;
+	}
+
+	if ( ($sstatinfo[0] == $dstatinfo[0]) &&
+	     ($sstatinfo[1] != $dstatinfo[1])) {
+		if ($sstatinfo[7] == $dstatinfo[7]) {
+			link_two_files($sfilename, $dfilename);
+
+		} else {
+			my $err = sprintf("ERROR: File sizes are not the same, cannot relink %s to %s.\n",
+				$sfilename, $dfilename);
+			if ($fail_on_different_sizes) {
+				die $err;
+			} else {
+				warn $err;
+			}
+		}
+
+	} elsif ( ($sstatinfo[0] == $dstatinfo[0]) &&
+	     ($sstatinfo[1] == $dstatinfo[1])) {
+		$already++;
+	}
+}
+
+sub get_canonical_form($) {
+	my $dir = shift;
+	my $original = $dir;
+
+	die "$dir is not a directory." unless -d $dir;
+
+	$dir .= "/" unless $dir =~ m#/$#;
+	$dir .= ".git/" unless $dir =~ m#\.git/$#;
+
+	die "$original does not have a .git/ subdirectory.\n" unless -d $dir;
+
+	return $dir;
+}
+
+sub link_two_files($$) {
+	my ($sfilename, $dfilename) = @_;
+	my $tmpdname = sprintf("%s.old",$dfilename);
+	rename($dfilename,$tmpdname)
+		or die sprintf("Failure renaming %s to %s: %s",
+			$dfilename, $tmpdname, $!);
+
+	if (! link($sfilename,$dfilename)) {
+		my $failtxt = "";
+		unless (rename($tmpdname,$dfilename)) {
+			$failtxt = sprintf(
+				"Git Repository containing %s is probably corrupted, " .
+				"please copy '%s' to '%s' to fix.\n",
+				$tmpdname, $dfilename);
+		}
+
+		die sprintf("Failed to link %s to %s: %s\n%s" .
+			$sfilename, $dfilename,
+			$!, $dfilename, $failtxt);
+	}
+
+	unlink($tmpdname)
+		or die sprintf("Unlink of %s failed: %s\n",
+			$dfilename, $!);
+
+	$linked++;
+}
+
+
+sub usage() {
+	print("Usage: $0 [--safe] <dir> [<dir> ...] <master_dir> \n");
+	print("All directories should contain a .git/objects/ subdirectory.\n");
+	print("Options\n");
+	print("\t--safe\t" .
+		"Stops if two objects with the same hash exist but " .
+		"have different sizes.  Default is to warn and continue.\n");
+	exit(1);
+}
-- 

Ryan Anderson
  sometimes Pug Majere

^ permalink raw reply

* Re: [PATCH] Add git-relink-script to fix up missing hardlinks
From: Jeff Garzik @ 2005-06-26 18:36 UTC (permalink / raw)
  To: Ryan Anderson; +Cc: Linus Torvalds, git, Junio C Hamano
In-Reply-To: <20050626181516.GC20369@mythryan2.michonline.com>

Ryan Anderson wrote:
> Add git-relink-script
> 
> This will scan 2 or more object repositories and look for common objects, check
> if they are hardlinked, and replace one with a hardlink to the other if not.
> 
> This version warns when skipping files because of size differences, and
> handle more than 2 repositories automatically.
> 
> Signed-off-by: Ryan Anderson <ryan@michonline.com>

Thanks for posting this.

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Junio C Hamano @ 2005-06-26 18:39 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David S. Miller, Git Mailing List, Nicolas Pitre, Chris Mason
In-Reply-To: <Pine.LNX.4.58.0506260905200.19755@ppc970.osdl.org>

>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:

LT> I actually like this approach better than having delta-objects in the
LT> filesystem. Partly because the pack-file is self-contained, partly because
LT> it also solves the fs blocking issue, yet is still efficient to look up
LT> the results without having hardlinks etc to duplicate objects virtually.  
LT> And when you do the packing by hand as an "archival" mechanism, it also
LT> doesn't have any of the downsides that Chris' packing approach had.

After analyzing what is involved in making packed GIT integrated
into read_sha1_file() [*1*], I agree 100% with the above.  I
mean no disrespect to what Nico has done (and I myself have done
some code to work with Nico's deltified objects when I did diffs
and pull fixes), but it would help the code very much if we do
not have to worry about "delta" objects in GIT_OBJECT_DIRECTORY.

My preference is to do things in this order:

 (0) concatenate pack and idx files;

 (1) teach read_sha1_file() to read from packed GIT;

 (2) teach fsck-cache about packed GIT;

 (3) have people with deltified repositories convert them back
     to undeltified (I think git-pack-objects would barf on such
     repository);

 (4) drop "delta" objects from GIT_OBJECT_DIRECTORY; this means
     that git-deltafy-script and git-mkdelta have to go.

 (5) tell git-*-pull about packed GIT;


[Footnotes]

*1* Here is the analysis I did last night, still assuming that
we would support "delta" objects in GIT_OBJECT_DIRECTORY.  The
"trickier" map_sha1_file() users almost all involve "delta"
objects, and that is why I prefer dropping them.

 - Enhance GIT_ALTERNATE_OBJECT_DIRECTORIES mechanism so that
   its component can be either a directory or a packed file.

 - sha1_file.c::find_sha1_file() has to be enhanced to express
   not just path (in the current "individual object file"
   case) but a pointer to a structure that describes a packed
   file in the GIT_ALTERNATE_OBJECT_DIRECTORIES list with the
   offset for the entry.

 - The change necessary to sha1_file.c::has_sha1_file() is
   minimum.  find_sha1_file() updated along the above lines
   would say if the thing exists or not anyway, so it can just
   return true/false as it currently does pretty easily.

 - sha1_file.c::read_sha1_file() would be the primary piece to
   unpack from the packed representation.

 - sha1_file.c::map_sha1_file() is trickier.  It has handful
   callers outside sha1_file.c for valid reasons, so we will
   need to audit the callers and have them fall back on
   read_sha1_file() as appropriate.  Here is the result of my
   first pass:

   - (easy) sha1_delta_base() is used only when an object is
     delitified, and if true get to the base object.  We can
     just tell the caller our object is not deltified when it
     resides in a packed file.

   - (easy) sha1_file_size() is used by diffcore to measure the
     expanded blob size.  Although the implementation obviously
     has to be different, it would be trivial to find the size
     if the object resides in a packed file.

   - (easy) pack-objects.c::check_object() uses map_sha1_file() so that
     it can unpack small to get the type of the object.  We
     should be able to introduce a new interface (say,
     sha1_file.c::sha1_object_type()) for doing this sort of
     stuff.

   - (harder) mkdelta.c::get_buffer(), object.c::parse_object()
     and delta.c::process_delta() are trickier, because they
     want to treat "delta" as a raw object (otherwise we would
     have just done sha1_read_file() instead of
     map/unpack_sha1_file pair).

   - (harder) ssh-push.c::serve_object() also wants raw
     representation to directly ship to the other end.

^ permalink raw reply

* Re: [PATCH] Add git-relink-script to fix up missing hardlinks
From: Junio C Hamano @ 2005-06-26 19:07 UTC (permalink / raw)
  To: Ryan Anderson; +Cc: git, Junio C Hamano
In-Reply-To: <20050626181516.GC20369@mythryan2.michonline.com>

Not that I think it matters that much anymore since I am
proposing removal of "delta" support and Linus seems to be
inclined in the same direction, but I said "most of the time" in
the earlier message on this same topic for a reason:

    Message-ID: <7vy89h36da.fsf@assigned-by-dhcp.cox.net>
    Subject: Re: RFE: git relink
    Date: Fri, 10 Jun 2005 20:44:01 -0700
    References: <42A88C07.5050907@pobox.com>

    Whoever is doing this script needs to be a bit careful.

    ...

    Ryan Anderson code will notice delta vs full object case most of
    the time because it checks and makes sure the sizes of
    corresponding files from two repositories match.  The problem
    with the code is that it dies, instead of just ignoring, when
    size differs....

Your latest version has an option not to die which is very good
[*1*], but in a very narrow corner case, without comparing the
file contents, I think the code would still do a wrong thing.
Two trees can store the same object both in delitified form but
based on different base objects, and the deltified
representation still having the same length, no?  And I suspect
you would end up linking them together, corrupting one of the
trees.

Of course, even when you do not have "delta", if an object in
one tree is corrupted (but has the correct size), you would end
up relinking the corrupt one into another tree, nuking a good
copy, if you do not compare the file contents.

If/when/after the proposed removal of "delta" support happens, I
think the correct way to do git-relink-script would be to keep
most of your latest version intact, except:

 (1) make it always die when you see differences in size.
     Without "delta" in the repository, SHA1 files that
     represent the same object must have the same size.

 (2) make --safe also check on file contents.  You do not need
     the flag for the "delta" reason anymore, so I am suggesting
     reusing the flag to detect file corruption, to be extra
     safe, when the user permits you to spend cycles to be more
     careful.

[Footnote]

*1* and other parts of the script all look nicely done.

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Linus Torvalds @ 2005-06-26 19:19 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: David S. Miller, Git Mailing List, Nicolas Pitre, Chris Mason
In-Reply-To: <7vzmtdq7wy.fsf@assigned-by-dhcp.cox.net>



On Sun, 26 Jun 2005, Junio C Hamano wrote:
> 
> My preference is to do things in this order:
> 
>  (0) concatenate pack and idx files;

Actually, I was originally planning to do that, but now that I have 
thought about what read_sha1_file() would actually do, I think it's more 
efficient to leave the index as a separate file.

In particular, what you'd normally do is that if you can't look up the
file in the regular object directory, you start going through the pack
files. You can do it by having GIT_ALTERNATE_OBJECT_DIRECTORIES point to a
pack file, but I actually would prefer the notion of just adding a

	.git/objects/pack

subdirectory, and having object lookup just automatically open and map all 
index files in that subdirectory.

And the thing is, you really just want to map the index files, the data
files can be so big that you can't afford to map them (ie a really big
project might have several pack-files a gig each or something like that).

And the most efficient way to map just the index file is to keep it 
separate, because then the "stat()" will just get the information 
directly, and you then just mmap that. 

The alternative is to first read the index of the index (to figure out how
big the index is), and then map the rest. But that just seems a lot
messier than just mapping the index file directly.

And when creating these things, we do need to create the data file (which 
can be big enough that it doesn't fit in memory) first, so we have to have 
a separate file for it, we can't just stream it out to stdout.

Now, when _sending_ the pack-files, linearizing them is easy: you just 
send the index first, and the data file immediately afterwards. The index 
tells how big it is, so there's no need to even add any markers: you can 
do something like 'git-send-script' with something simple like

	git-rev-list ... | git-pack-file tmp-pack &&
	cat tmp-pack.idx tmp-pack.data | ssh other git-receive-script

So let's just keep the index/data files separate.

		Linus

^ permalink raw reply

* Re: [PATCH] Add git-relink-script to fix up missing hardlinks
From: Junio C Hamano @ 2005-06-26 19:31 UTC (permalink / raw)
  To: Ryan Anderson; +Cc: git, Linus Torvalds, Jeff Garzik
In-Reply-To: <7v7jghq6lt.fsf@assigned-by-dhcp.cox.net>

>>>>> "JCH" == Junio C Hamano <junkio@cox.net> writes:

JCH> Your latest version has an option not to die which is very
JCH> good, but in a very narrow corner case, without comparing
JCH> the file contents, I think the code would still do a wrong
JCH> thing.

Having said that, the corner case is narrow enough (and
hopefully to be gone soon) that I think the current version is
perfectly acceptable for inclusion.

Linus, please apply.  What it does is useful to encourage the
"one topic, one tree" use pattern, the officially recommended
way IIUC.

I am a bit puzzled, though, why Jeff was the original requestor
for this feature --- I thought he handles 50 heads in one
repository which means there is no multiple repositories to
relink across.

^ permalink raw reply

* [PATCH] git-ssh-pull: commit-id consistency
From: Sven Verdoolaege @ 2005-06-26 19:45 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Daniel Barkalow, git

I thought about keeping the check for a leading dot or slash,
but then I figured that you'd get an error from the other
side pretty quickly.

skimo
--
In contrast to other plumbing tools, git-ssh-pu{sh,ll} only
allow a very restrictive form of commit-id filenames.
This patch removes this restriction.

Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>

---
commit 00437f1bafcb710bb809cd2e87cdaeae340a67b8
tree 480e77cde9afbd0b0abd33e3f272288739b01a7e
parent 641e1cac73acd67d0b1830dfd7196bca58dffbf2
author Sven Verdoolaege <skimo@kotnet.org> Sun, 26 Jun 2005 19:41:44 +0200
committer Sven Verdoolaege <skimo@kotnet.org> Sun, 26 Jun 2005 19:41:44 +0200

 pull.c     |    7 ++-----
 ssh-push.c |    2 +-
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/pull.c b/pull.c
--- a/pull.c
+++ b/pull.c
@@ -152,11 +152,8 @@ static int interpret_target(char *target
 {
 	if (!get_sha1_hex(target, sha1))
 		return 0;
-	if (!check_ref_format(target)) {
-		if (!fetch_ref(target, sha1)) {
-			return 0;
-		}
-	}
+	if (!fetch_ref(target, sha1))
+		return 0;
 	return -1;
 }
 
diff --git a/ssh-push.c b/ssh-push.c
--- a/ssh-push.c
+++ b/ssh-push.c
@@ -74,7 +74,7 @@ int serve_ref(int fd_in, int fd_out)
 			return -1;
 		posn++;
 	} while (ref[posn - 1]);
-	if (get_ref_sha1(ref, sha1))
+	if (get_sha1(ref, sha1))
 		remote = -1;
 	write(fd_out, &remote, 1);
 	if (remote)

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Junio C Hamano @ 2005-06-26 19:45 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David S. Miller, Git Mailing List, Nicolas Pitre, Chris Mason
In-Reply-To: <Pine.LNX.4.58.0506261206170.19755@ppc970.osdl.org>

>>>>> "LT" == Linus Torvalds <torvalds@osdl.org> writes:

LT> On Sun, 26 Jun 2005, Junio C Hamano wrote:
>> 
>> My preference is to do things in this order:
>> 
>> (0) concatenate pack and idx files;

LT> So let's just keep the index/data files separate.

Fair enough.  Having thought about it a bit more, if people
agree, I think it would make more sense to rip out "delta"
object support first before doing read_sha1_file() and friends
that uses .git/objects/pack.

My "preferred order" now look like this:

 (1) have people with deltified repositories convert them back
     to undeltified (I think git-pack-objects would barf on such
     repository);

 (2) drop "delta" objects from GIT_OBJECT_DIRECTORY; this means
     that git-deltafy-script and git-mkdelta have to go.

 (3) teach read_sha1_file() to read from packed GIT in
     .git/objects/pack;

 (4) teach fsck-cache about packed GIT;

 (5) tell git-*-pull about packed GIT;

^ permalink raw reply

* Re: [PATCH] Add git-relink-script to fix up missing hardlinks
From: Jeff Garzik @ 2005-06-26 19:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Ryan Anderson, git, Linus Torvalds
In-Reply-To: <7vy88wq5hs.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:
> I am a bit puzzled, though, why Jeff was the original requestor
> for this feature --- I thought he handles 50 heads in one
> repository which means there is no multiple repositories to
> relink across.

Sure there are.  Just watching my submissions on the mailing list, you 
can see ones mentioned such as "misc-2.6", "libata-dev", "netdev-2.6", etc.:

[jgarzik@pretzel repo]$ ls -FC
  config-2.4      ethtool/    libata-dev/  netdev-2.6/     sparse/
  config-2.6      git/        linux-2.6/   old-SCM/
  config-2.6-uml  git-tools/  misc-2.6/    scsi-misc-2.6/

And I always keep an unmodified 'vanilla' tree from which everything is 
sourced (and hardlinked to).

It's a categorization system, a namespace.  Top-level repositories are 
broad categories, and branches sub-divide those categories.

	Jeff

^ permalink raw reply

* Re: [PATCH] git-ssh-pull: commit-id consistency
From: Daniel Barkalow @ 2005-06-26 20:11 UTC (permalink / raw)
  To: Sven Verdoolaege; +Cc: Linus Torvalds, git
In-Reply-To: <20050626214547.A29432@tin.liacs.nl>

On Sun, 26 Jun 2005, Sven Verdoolaege wrote:

> I thought about keeping the check for a leading dot or slash,
> but then I figured that you'd get an error from the other
> side pretty quickly.
> 
> skimo
> --
> In contrast to other plumbing tools, git-ssh-pu{sh,ll} only
> allow a very restrictive form of commit-id filenames.
> This patch removes this restriction.

There are a few problems with this: not all pull methods can handle
vagueness; HTTP, for instance, needs to know exactly what URL to request,
and it can't deal with having the user request just anything. Also, it's
not particularly useful to support just anything as the hash to start
from, when you have to specify exactly the file to write the ref to (the
-w argument), which would be a lot more difficult and flaky, because we
can't just look for the only thing that works.

More generally, I think we should require explicit instructions, even when
we might be able to figure things out, when we're moving data between
repositories, similar to how we are strict about the data stored in
repositories (although, of course, we need to support a few more cases).

In addition, I think that stuff outside of objects/ and refs/ (and, when
we have something in it, info/) should be considered private, and not
transmitted from place to place.

One thing that might be a good idea, however, is to allow using symlinks
from .git/ to refs/<x>/<y> on the local side of git-ssh-push by converting
them to <x>/<y>. That way, when you push "HEAD", it will actually push
refs/heads/my-current-branch instead. Of course, the -w issue remains,
because you may have different names on the other side (i.e., on the local
side, it might be refs/heads/new-diff-algo, but the remote side might be
refs/heads/my-latest).

Really, the right solution is to keep this sort of info somewhere and have 
scripts do the right thing with exact specifications.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Chris Mason @ 2005-06-26 20:52 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Jeff Garzik, David S. Miller, Git Mailing List, Nicolas Pitre
In-Reply-To: <Pine.LNX.4.58.0506260905200.19755@ppc970.osdl.org>

On Sunday 26 June 2005 12:41, Linus Torvalds wrote:
> On Fri, 24 Jun 2005, Linus Torvalds wrote:
> > yeah, it clearly needs some refining to be useful, but I think you can
> > kind of see how it would work.
>
> Ok, here's how it works.
>
>  - Pick a starting commit (or a hundred)
>
>  - Pick an ending commit (or a hundred)
>
>  - generate the list of objects in between them
>
> 	git-rev-list --object end ^start > object-list
>
>  - Pack that list of objects into an "object pack":
>
> 	git-pack-objects out < object-list

Without having read the code, the big thing that hurt performance in my early 
packed file work was compressing the whole packed file instead of individual 
sub-objects.  It takes more room to compress each object, but when I 
compressed the whole thing read performance was quite bad.

-chris

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Chris Mason @ 2005-06-26 21:03 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Jeff Garzik, David S. Miller, Git Mailing List, Nicolas Pitre
In-Reply-To: <200506261652.59373.mason@suse.com>

On Sunday 26 June 2005 16:52, Chris Mason wrote:
> >
> > 	git-rev-list --object end ^start > object-list
> >
> >  - Pack that list of objects into an "object pack":
> >
> > 	git-pack-objects out < object-list
>
> Without having read the code, the big thing that hurt performance in my
> early packed file work was compressing the whole packed file instead of
> individual sub-objects.  It takes more room to compress each object, but
> when I compressed the whole thing read performance was quite bad.

Sorry, fat fingered the send key...

The hard links were the biggest problem with my packed file patches, I think 
the dynamic lookup in a separate packed file index is the best way to go.

-chris

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Linus Torvalds @ 2005-06-26 21:40 UTC (permalink / raw)
  To: Chris Mason; +Cc: Jeff Garzik, David S. Miller, Git Mailing List, Nicolas Pitre
In-Reply-To: <200506261652.59373.mason@suse.com>



On Sun, 26 Jun 2005, Chris Mason wrote:
> 
> Without having read the code, the big thing that hurt performance in my early 
> packed file work was compressing the whole packed file instead of individual 
> sub-objects.  It takes more room to compress each object, but when I 
> compressed the whole thing read performance was quite bad.

Since I wanted random-access, compressing the whole thing just wasn't an 
option.

Besides, the big space savings come from finding deltas, which is 
obviously also a compression, just at a higher level. The biggest problem 
there is to find a guess of objects to try to delta against, and right now 
that part is pretty stupid and could possibly be improved (it just sorts 
objects by size and tries to delta against "close" objects).

To generate a better sort _would_ actually be pretty close to doing a 
global compression (it really does boil down to the same thing: finding 
big sub-sequences, except it's in a "fragmented" space), but one issue is 
that I don't want to read in the whole data set in one go, so it would 
have to be based on some rolling hash or something. Davide pointed to 
rzip, and a variation of that (which knows about object boundaries) might 
work.

(You can also sort by filename, if you want to try. I don't track
filenames at all there and it's actually non-trivial to do, so that would
require some new and pretty nasty code, but it's possible in _theory_ at
least.)

Anyway, that's all potential improvement for generating better packing,
and it should certainly be possible without changing the format - just
generate a better initial sort, in otder to find more deltas (or rather,
find them faster by using a smaller window size).

So the stupid sort I have now does actually work, but exactly because it's
so stupid it wants a big window for best packing (because there might be a
lot of objects that aren't interesting), which in turn is quite expensive.
So a better sort would make a smaller window more effective.

[ Some numbers: a window of 10 objects is the default, and packs the
  current kernel down to 77MB in 2m21s. A window of 20 objects improves
  that packing to 71MB, but makes the packing time go up to 3m36s for me.  
  And a window of 100 gets us down to 62M but takes 11m54s.

  A window of 200 (with a delta depth of 200 too - likely _way_ too deep
  for normal use) gives you a 59M pack, but takes 20m59s, so there's
  definitely a point of diminishing returns.

  This is all for the current HEAD, which takes up 264M the "traditional" 
  git way and takes 141M without any deltas, just packed tightly with no 
  filesystem blocking.

  Now, as you can notice that's actually a slightly sub-linear increase in
  time, because as we find a delta, we will only accept smaller deltas in
  the future, so we can often stop comparing even before we've reached the
  maximum window size, and so effort is slightly less than linear because 
  there's effectively a constant component to part of it.

  Also, the good news is that you probably don't want to generate one 
  humungous pack archive anyway, but you're likely better off doing a new 
  incremental pack every few months. So we'll never have the situation 
  that creating a pack gets increasingly more costly, since at some point 
  you just say "ok, I created a perfect pack for the first 4 months of
  development, I'll now do subsequent packs on top of that instead".

  The other good news is that a pack is also a natural boundary for fsck 
  (as in "ok, I found that object in a pack, so I won't bother going
  deeper in the reachability chain"), so if you start packing your
  repository, fsck will only have to worry about the objects that are
  unpacked. That makes them work really naturally for archiving, ie this 
  all means that you can avoid a lot of overhead by packing your history
  every once in a while, with it all being entirely transparent.

  In other words, if you just pack every month, you can basically 
  guarantee that fsck costs etc never really go up, and your diskspace 
  also goes up only very slowly. The packed format is quite efficient in 
  many ways, but it is totally immutable (ie you can't add anything to an 
  archive - a pack stays the way it always was, and if you want to pack 
  more you have to either re-do the pack or just create a new one) ]

		Linus

^ permalink raw reply

* 'dotest' script broken
From: Jeff Garzik @ 2005-06-26 21:43 UTC (permalink / raw)
  To: Linus Torvalds, Git Mailing List


When I run 'dotest /g/tmp/mbox' I receive an error message

	[jgarzik@pretzel netdev-2.6]$ dotest /g/tmp/mbox
	mailinfo msg-file path-file filelist-file < email

and if you look at the dotest script, it only passes 2 args to mailinfo, 
not the 3 args that the above usage message appears to require:

for i in .dotest/*
do
         mailinfo .dotest/msg .dotest/patch < $i > .dotest/info || exit 1
	...

^ permalink raw reply

* Re: 'dotest' script broken
From: Linus Torvalds @ 2005-06-26 21:51 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Git Mailing List
In-Reply-To: <42BF2167.9030404@pobox.com>



On Sun, 26 Jun 2005, Jeff Garzik wrote:
> 
> When I run 'dotest /g/tmp/mbox' I receive an error message
> 
> 	[jgarzik@pretzel netdev-2.6]$ dotest /g/tmp/mbox
> 	mailinfo msg-file path-file filelist-file < email
> 
> and if you look at the dotest script, it only passes 2 args to mailinfo, 
> not the 3 args that the above usage message appears to require:
> 
> for i in .dotest/*
> do
>          mailinfo .dotest/msg .dotest/patch < $i > .dotest/info || exit 1

Looks like you updated "dotest", but didn't update "mailinfo"? Why? 
Especially as they come in the same package..

The new mailinfo wants just two arguments to match the new dotest.

			Linus

^ permalink raw reply

* Re: kernel.org and GIT tree rebuilding
From: Linus Torvalds @ 2005-06-26 22:34 UTC (permalink / raw)
  To: Chris Mason; +Cc: Jeff Garzik, David S. Miller, Git Mailing List, Nicolas Pitre
In-Reply-To: <Pine.LNX.4.58.0506261359370.19755@ppc970.osdl.org>



On Sun, 26 Jun 2005, Linus Torvalds wrote:
> 
> (You can also sort by filename, if you want to try. I don't track
> filenames at all there and it's actually non-trivial to do, so that would
> require some new and pretty nasty code, but it's possible in _theory_ at
> least.)

Heh. It's actually very easy if you don't take the "name" too seriously, 
and you just pick some random one, namely the first one that was used to 
reach the entry.

Then, you might sort the objects on a hash based on the name, and get 
tons of cheap deltas close-by.

It is _uglee_, but hey, it's a heuristic, and it happens to work pretty 
well. It brought the kernel pack down to 59M even with just a small window 
of 10.

Thanks to Davide for making me think about this hack, although he talked 
about something much more proper (and harder) than this quick and 
ugly heuristic ;)

The main change is that "git-rev-list --objects" has been changed to show
the name the object was reached through.

			Linus

^ permalink raw reply

* Re: 'dotest' script broken
From: Jeff Garzik @ 2005-06-26 22:39 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.58.0506261450000.19755@ppc970.osdl.org>

Linus Torvalds wrote:
> Looks like you updated "dotest", but didn't update "mailinfo"? Why? 


Duh.  I was so used to just updating git-tools without 'make install'

Sorry for the noise.

	Jeff

^ permalink raw reply

* Re: [PATCH] Add git-relink-script to fix up missing hardlinks
From: Jan Harkes @ 2005-06-27  1:11 UTC (permalink / raw)
  To: git
In-Reply-To: <42BF058F.8010301@pobox.com>

On Sun, Jun 26, 2005 at 03:44:15PM -0400, Jeff Garzik wrote:
> Junio C Hamano wrote:
> >I am a bit puzzled, though, why Jeff was the original requestor
> >for this feature --- I thought he handles 50 heads in one
> >repository which means there is no multiple repositories to
> >relink across.
> 
> Sure there are.  Just watching my submissions on the mailing list, you 
> can see ones mentioned such as "misc-2.6", "libata-dev", "netdev-2.6", etc.:
> 
> [jgarzik@pretzel repo]$ ls -FC
>  config-2.4      ethtool/    libata-dev/  netdev-2.6/     sparse/
>  config-2.6      git/        linux-2.6/   old-SCM/
>  config-2.6-uml  git-tools/  misc-2.6/    scsi-misc-2.6/

I actually have been using subdirectories in refs/heads with quite a bit
of success. All of the core tools have no problem with them and only
gitweb and gitk need some small changes to show them correctly.

The subdirectories in refs/heads are user specific in my case, this end
up being pretty useful when combined with Coda's directory ACLs, each
user can maintain their own branches, but cannot modify anyone elses.
All developers have insert, read and lookup rights on the main objects
repository, they can add new objects, but not remove or overwrite any
existing ones.

My branch names end up looking something like 'jaharkes/wdonly',
'awolbach/expand', etc. and it works like a charm.

Jan

^ permalink raw reply

* git-local-pull
From: David S. Miller @ 2005-06-27  3:05 UTC (permalink / raw)
  To: git


I tried to start using git-clone-script to clone repositories
locally.  It crunches on the disk for a couple of seconds,
that's fine, but then I notice the disk activity stop and
git-local-pull becomes cpu bound and grows to 80MB in size
over the course of 5 minutes.

Is this a side effect of the new pack/unpack stuff?

Compared to what this thing is doing, manually symlinking
the object database, copying over the HEAD, and building
the index file is significantly faster.

Actually, git-clone-script didn't build an index file.
So the compute time definitely came from something else
entirely.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox