Git development
 help / color / mirror / Atom feed
* Re: Unresolved issues #2
From: Junio C Hamano @ 2006-05-07  9:42 UTC (permalink / raw)
  To: git
In-Reply-To: <7vy7xekwbs.fsf@assigned-by-dhcp.cox.net>

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

> But what about prefersymlinkrefs one?  When setting the variable
> to such a non-standard value, it is unreasonable for people to
> want to justify why with a comment like the above.

Obviously I was not reading what I was typing.  It is very
reasonable for people to want to do that.  Sorry.

^ permalink raw reply

* Re: Unresolved issues #2
From: Johannes Schindelin @ 2006-05-07 11:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vy7xekwbs.fsf@assigned-by-dhcp.cox.net>

Hi,

On Sun, 7 May 2006, Junio C Hamano wrote:

> [...] Probably a reasonable convention would be to define the config 
> file format to be something like this:
> 
>         <comment that applies to the section>
>         [section]
>                 <comment that applies to the variable stands on
> 		 its own before the variable>
>                 variable [= value] <comment that applies to the
>         			    fact the variable is set to
>                                     this particular value starts
> 				    on the same line as the
>                                     "variable = value" thing>
> 
>  - when a variable is reset to another value, remove the
>    "value comment";
>  - when a variable disappears, remove "variable comment";
>  - when a section disappears, remove "section comment";
>  - otherwise leave the comment intact.
> 
> Then we could tell the user the rule is like above, and tell
> them to structure the file with comments that way, if they ever
> want to edit the file by hand.
> 
> Now if we wanted to do something like the above, I suspect that
> it would be easier and less error prone to first scan the config
> file, note what appears where, and do the processing in-core,
> and then write the results out, perhaps using data structures
> like these:
> 
>         struct config_section {
>             char *pre_comment;
>             char *name; /* e.g. "core" */
>             struct config_section *next; /* next section */
>             struct config_var *vars; /* pointer to the first one */
>         };
>         struct config_var {
>             char *pre_comment;
>             char *name;
>             char *value; /* "existence" bool may have NULL,
>                           * otherwise probably a string "= value"
>                           */
>             char *value_comment;
>             struct config_var *next; /* pointer to the next one
>                                       * in the section
>                                       */
>         };
> 
> Obviously, data structures like these would make it even easier
> if we decide we do _not_ care about comments (we would just lose
> x_comment fields, parse the thing and write the resulting list
> out).

Sounds very reasonable.

Ciao,
Dscho

^ permalink raw reply

* Re: Unresolved issues #2
From: Jakub Narebski @ 2006-05-07 11:38 UTC (permalink / raw)
  To: git
In-Reply-To: <7vy7xekwbs.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

>             char *value; /* "existence" bool may have NULL,
>                           * otherwise probably a string "= value"
>                           */

Probably " = value" to preserve whitespace (e.g. justify on equal sign in
hand crafted config file).

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: [PATCH] config: mmap() the contents of the config file
From: Johannes Schindelin @ 2006-05-07 11:40 UTC (permalink / raw)
  To: git, junkio
In-Reply-To: <Pine.LNX.4.63.0605070103270.26358@wbgn013.biozentrum.uni-wuerzburg.de>

Hi,

On Sun, 7 May 2006, Johannes Schindelin wrote:

> This makes it possible to rewrite the config without accessing the config
> file twice.

Since commit c2b9e699, this is needed, too:

diff --git a/config.c b/config.c
index 59006fa..30effe3 100644
--- a/config.c
+++ b/config.c
@@ -362,7 +362,7 @@ static int store_aux(const char* key, co
 		} else if (strrchr(key, '.') - key == store.baselen &&
 			      !strncmp(key, store.key, store.baselen)) {
 					store.state = SECTION_SEEN;
-					store.offset[store.seen] = ftell(config_file);
+					store.offset[store.seen] = config_offset;
 		}
 	}
 	return 0;
-- 
1.3.2.g4e38b-dirty

^ permalink raw reply related

* Re: Unresolved issues #2 (shallow clone again)
From: Jakub Narebski @ 2006-05-07 13:30 UTC (permalink / raw)
  To: git
In-Reply-To: <7v1wv92u7o.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> The vocabulary we would want from the requestor side is probably
> (at least):
> 
>         I WANT to have these
>         I HAVE these
>         I'm MISSING these
>         Don't bother with these this time around (--since, ^v2.6.16, ...)

Wouldn't it be easier (sorry, no code yet) to have the following:

        I WANT to have these
        I HAVE these
        These are GRAFT PARENTLESS        

with the target side sending list of all parentless commits in the
info/grafts file. The source side will then do the grafting 'in memory' and
send the packs like normal, only with those cauterizing grafts in place.

Now I'm waiting for someone to say that it is too simple and cannot be done,
or that shallow clone/shallow fetch uses this method...

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* [PATCH] Sparse fix for builtin-diff
From: Peter Hagervall @ 2006-05-07 14:50 UTC (permalink / raw)
  To: junkio; +Cc: git

You gotta love sparse:

builtin-diff.c:88:4: error: Just how const do you want this type to be?

Signed-off-by: Peter Hagervall <hager@cs.umu.se>
---

 builtin-diff.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/builtin-diff.c b/builtin-diff.c
index 636edbf..d3ac581 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -84,8 +84,7 @@ static void stuff_change(struct diff_opt
 
 	if (opt->reverse_diff) {
 		unsigned tmp;
-		const
-			const unsigned char *tmp_u;
+		const unsigned char *tmp_u;
 		const char *tmp_c;
 		tmp = old_mode; old_mode = new_mode; new_mode = tmp;
 		tmp_u = old_sha1; old_sha1 = new_sha1; new_sha1 = tmp_u;

^ permalink raw reply related

* Re: Unresolved issues #2 (shallow clone again)
From: Linus Torvalds @ 2006-05-07 15:27 UTC (permalink / raw)
  To: Jeff King; +Cc: git
In-Reply-To: <20060507075631.GA24423@coredump.intra.peff.net>



On Sun, 7 May 2006, Jeff King wrote:
>
>   - Total savings by going shallow: 10.7%
> 
> So basically, trees and commits DON'T compress as well as historical
> blobs (potentially because git-pack-objects isn't currently optimized
> for this -- I haven't checked). As a result, we're saving only 10% by
> going shallow instead of a potential 50%.

The biggest size savers from packing is (in rough order of relevance, if 
I recall the rough statistics I did):

 - avoiding block boundaries. 
 - delta packing of blobs
 - delta packing of trees
 - regular compression

The block boundaries are huge, we have tons of small objects, and that was 
one of the primary reasons for packing. I'd suspect that this is a 3:1 
factor for a lot of things for many "common" filesystem setups. You 
probably didn't even account for the size of inodes in your "du" setup.

And blobs with history generally delta very well (_much_ better than 
regular compression).

Trees should _delta_ very well, but they basically don't compress, 
especially after deltaing. The SHA1's are totally incompressible (in a 
tree they aren't even ASCII), and as a deta, the names won't compress much 
either because they are short.

Commits are fairly small, shouldn't delta all that much, and they don't 
even compress _that_ well either (they're normal text and often have some 
redundancy with the committer and author being the same, but they are 
short and have some fairly incompressible elements, so..)

The thing with trees in particular is that they are very common for the 
kernel (and probably not so much for many other projects). A single commit 
ends up quite commonly being just one commit object, one blob (that deltas 
really well), and three or four trees. Merges often have no new blobs at 
all, just several new trees and the commit object.

So a huge amount of the wins from packing come from the file _history_, 
the part that a shallow clone (on purpose) leaves behind. 

The regular compression will pick up a fair amount of slack with the 
blobs, but it's a much smaller factor than the delta compression for 
something that has a long history.

It's somewhat interesting to note that over the year that we've used git, 
the kernel pack-size hasn't even increased all that much. I forget exactly 
what it was when we started packing, but it was on the order of ~75M. It 
is now 115M for me. And the old linux-history thing (full BK history over 
three years) is 177M - not much more than twice the size of just a few 
kernel versions - with some higher packing ratios..

Exactly because blobs delta so incredibly well.

		Linus

^ permalink raw reply

* [PATCH] Fix crash when reading the empty tree
From: Johannes Schindelin @ 2006-05-07 15:42 UTC (permalink / raw)
  To: git, junkio


cvsimport needs to call git-read-tree without arguments to create an empty
tree.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
 read-tree.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/read-tree.c b/read-tree.c
index 067fb95..a060a97 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -881,7 +881,7 @@ int main(int argc, char **argv)
 	 * valid cache-tree because the index must match exactly
 	 * what came from the tree.
 	 */
-	if (trees->item && (!merge || (stage == 2))) {
+	if (trees && trees->item && (!merge || (stage == 2))) {
 		cache_tree_free(&active_cache_tree);		
 		prime_cache_tree();
 	}
-- 
1.3.2.g5131-dirty

^ permalink raw reply related

* [PATCH] core-tutorial.txt: escape asterisk
From: Matthias Lederhofer @ 2006-05-07 17:32 UTC (permalink / raw)
  To: git

---
I don't now exactly why, but this asterisk has to be escaped to show
up correctly in the html format.

 Documentation/core-tutorial.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

7e3a9fbafb8b6aa4ce460221a982feda06549215
diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt
index 4211c81..d1360ec 100644
--- a/Documentation/core-tutorial.txt
+++ b/Documentation/core-tutorial.txt
@@ -971,7 +971,7 @@ environment, is `git show-branch`.
 The first two lines indicate that it is showing the two branches
 and the first line of the commit log message from their
 top-of-the-tree commits, you are currently on `master` branch
-(notice the asterisk `*` character), and the first column for
+(notice the asterisk `\*` character), and the first column for
 the later output lines is used to show commits contained in the
 `master` branch, and the second column for the `mybranch`
 branch. Three commits are shown along with their log messages.
-- 
1.3.2

^ permalink raw reply related

* symlinks
From: Yakov Lerner @ 2006-05-07 17:47 UTC (permalink / raw)
  To: git

Hello,

I have a project that makes heavy use of symlinks in the source tree.
I added it to git, then cloned the repository, and all symlinks were
converted to plain files. What am I missing to preserve symlinks ?

Yakov

^ permalink raw reply

* Re: symlinks
From: Linus Torvalds @ 2006-05-07 18:07 UTC (permalink / raw)
  To: Yakov Lerner; +Cc: git
In-Reply-To: <f36b08ee0605071047h32ccef4bk76ac360ada1331a@mail.gmail.com>



On Sun, 7 May 2006, Yakov Lerner wrote:
> 
> I have a project that makes heavy use of symlinks in the source tree.
> I added it to git, then cloned the repository, and all symlinks were
> converted to plain files. What am I missing to preserve symlinks ?

You're not missing anything, it sounds like a bug. What did you use to 
clone, and what version? It definitely doesn't happen for me:

	mkdir symlink
	cd symlink/
	git-init-db 
	ln -s unknown new-link
	ls -l
	git add new-link 
	git commit

	cd 
	git clone symlink symlink2
	cd symlink2/
	ls -l

shows that the symlink was preserved.

But maybe there's a bug in some older version, or in some other clone 
protocol...

		Linus

^ permalink raw reply

* [PATCH] repack: honor -d even when no new pack was created
From: Martin Waitz @ 2006-05-07 18:18 UTC (permalink / raw)
  To: git

If all objects are reachable via an alternate object store then we
still have to remove all obsolete local packs.

Signed-off-by: Martin Waitz <tali@admingilde.org>

---

 git-repack.sh |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

c37df94d2b1633ce329bbe079805073b40a48548
diff --git a/git-repack.sh b/git-repack.sh
index e0c9f32..4fb3f26 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -48,15 +48,15 @@ name=$(git-rev-list --objects --all $rev
 	exit 1
 if [ -z "$name" ]; then
 	echo Nothing new to pack.
-	exit 0
-fi
-echo "Pack pack-$name created."
+else
+	echo "Pack pack-$name created."
 
-mkdir -p "$PACKDIR" || exit
+	mkdir -p "$PACKDIR" || exit
 
-mv .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
-mv .tmp-pack-$name.idx  "$PACKDIR/pack-$name.idx" ||
-exit
+	mv .tmp-pack-$name.pack "$PACKDIR/pack-$name.pack" &&
+	mv .tmp-pack-$name.idx  "$PACKDIR/pack-$name.idx" ||
+	exit
+fi
 
 if test "$remove_redundant" = t
 then
-- 
1.3.1.g6ef7

^ permalink raw reply related

* [PATCH] clone: keep --reference even with -l -s
From: Martin Waitz @ 2006-05-07 18:19 UTC (permalink / raw)
  To: git

Both -l -s and --reference update objects/info/alternates and used
to write over each other.

Signed-off-by: Martin Waitz <tali@admingilde.org>

---

 git-clone.sh               |    2 +
 t/t5700-clone-reference.sh |   78 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletions(-)
 create mode 100755 t/t5700-clone-reference.sh

3410837e34357d43a38a170691ca45f8f3a82221
diff --git a/git-clone.sh b/git-clone.sh
index 0805168..b785247 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -265,7 +265,7 @@ yes,yes)
 		test -f "$repo/objects/info/alternates" &&
 		cat "$repo/objects/info/alternates";
 		echo "$repo/objects"
-	    } >"$GIT_DIR/objects/info/alternates"
+	    } >>"$GIT_DIR/objects/info/alternates"
 	    ;;
 	esac
 	git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD"
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
new file mode 100755
index 0000000..916ee15
--- /dev/null
+++ b/t/t5700-clone-reference.sh
@@ -0,0 +1,78 @@
+#!/bin/sh
+#
+# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
+#
+
+test_description='test clone --reference'
+. ./test-lib.sh
+
+base_dir=`pwd`
+
+test_expect_success 'preparing first repository' \
+'test_create_repo A && cd A &&
+echo first > file1 &&
+git add file1 &&
+git commit -m initial'
+
+cd "$base_dir"
+
+test_expect_success 'preparing second repository' \
+'git clone A B && cd B &&
+echo second > file2 &&
+git add file2 &&
+git commit -m addition &&
+git repack -a -d &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'cloning with reference' \
+'git clone -l -s --reference B A C'
+
+cd "$base_dir"
+
+test_expect_success 'existance of info/alternates' \
+'test `wc -l <C/.git/objects/info/alternates` = 2'
+
+cd "$base_dir"
+
+test_expect_success 'pulling from reference' \
+'cd C &&
+git pull ../B'
+
+cd "$base_dir"
+
+test_expect_success 'that reference gets used' \
+'cd C &&
+echo "0 objects, 0 kilobytes" > expected &&
+git count-objects > current &&
+diff expected current'
+
+cd "$base_dir"
+
+test_expect_success 'updating origin' \
+'cd A &&
+echo third > file3 &&
+git add file3 &&
+git commit -m update &&
+git repack -a -d &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'pulling changes from origin' \
+'cd C &&
+git pull origin'
+
+cd "$base_dir"
+
+# the 2 local objects are commit and tree from the merge
+test_expect_success 'that alternate to origin gets used' \
+'cd C &&
+echo "2 objects" > expected &&
+git count-objects | cut -d, -f1 > current &&
+diff expected current'
+
+cd "$base_dir"
+
+test_done
-- 
1.3.1.g6ef7

^ permalink raw reply related

* [PATCH] Transitively read alternatives
From: Martin Waitz @ 2006-05-07 18:19 UTC (permalink / raw)
  To: git

When adding an alternate object store then add entries from its
info/alternates files, too.
Relative entries are only allowed in the current repository.
Loops and duplicate alternates through multiple repositories are ignored.
Just to be sure that nothing breaks it is not allow to build deep
nesting levels using info/alternates.

Signed-off-by: Martin Waitz <tali@admingilde.org>

---

 sha1_file.c |  178 +++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 106 insertions(+), 72 deletions(-)

34981f5467a86bb09120cc3c9637b98048fada04
diff --git a/sha1_file.c b/sha1_file.c
index 5464828..b62d0e3 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -217,6 +217,8 @@ char *sha1_pack_index_name(const unsigne
 struct alternate_object_database *alt_odb_list;
 static struct alternate_object_database **alt_odb_tail;
 
+static void read_info_alternates(const char * alternates, int depth);
+
 /*
  * Prepare alternate object database registry.
  *
@@ -232,14 +234,85 @@ static struct alternate_object_database 
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
-				 const char *relative_base)
+static int link_alt_odb_entry(const char * entry, int len, const char * relative_base, int depth)
 {
-	const char *cp, *last;
-	struct alternate_object_database *ent;
+	struct stat st;
 	const char *objdir = get_object_directory();
+	struct alternate_object_database *ent;
+	struct alternate_object_database *alt;
+	/* 43 = 40-byte + 2 '/' + terminating NUL */
+	int pfxlen = len;
+	int entlen = pfxlen + 43;
 	int base_len = -1;
 
+	if (*entry != '/' && relative_base) {
+		/* Relative alt-odb */
+		if (base_len < 0)
+			base_len = strlen(relative_base) + 1;
+		entlen += base_len;
+		pfxlen += base_len;
+	}
+	ent = xmalloc(sizeof(*ent) + entlen);
+
+	if (*entry != '/' && relative_base) {
+		memcpy(ent->base, relative_base, base_len - 1);
+		ent->base[base_len - 1] = '/';
+		memcpy(ent->base + base_len, entry, len);
+	}
+	else
+		memcpy(ent->base, entry, pfxlen);
+
+	ent->name = ent->base + pfxlen + 1;
+	ent->base[pfxlen + 3] = '/';
+	ent->base[pfxlen] = ent->base[entlen-1] = 0;
+
+	/* Detect cases where alternate disappeared */
+	if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) {
+		error("object directory %s does not exist; "
+		      "check .git/objects/info/alternates.",
+		      ent->base);
+		free(ent);
+		return -1;
+	}
+
+	/* Prevent the common mistake of listing the same
+	 * thing twice, or object directory itself.
+	 */
+	for (alt = alt_odb_list; alt; alt = alt->next) {
+		if (!memcmp(ent->base, alt->base, pfxlen)) {
+			free(ent);
+			return -1;
+		}
+	}
+	if (!memcmp(ent->base, objdir, pfxlen)) {
+		free(ent);
+		return -1;
+	}
+
+	/* add the alternate entry */
+	*alt_odb_tail = ent;
+	alt_odb_tail = &(ent->next);
+	ent->next = NULL;
+
+	/* recursively add alternates */
+	read_info_alternates(ent->base, depth + 1);
+
+	ent->base[pfxlen] = '/';
+
+	return 0;
+}
+
+static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
+				 const char *relative_base, int depth)
+{
+	const char *cp, *last;
+
+	if (depth > 5) {
+		error("%s: ignoring alternate object stores, nesting too deep.",
+				relative_base);
+		return;
+	}
+
 	last = alt;
 	while (last < ep) {
 		cp = last;
@@ -249,60 +322,15 @@ static void link_alt_odb_entries(const c
 			last = cp + 1;
 			continue;
 		}
-		for ( ; cp < ep && *cp != sep; cp++)
-			;
+		while (cp < ep && *cp != sep)
+			cp++;
 		if (last != cp) {
-			struct stat st;
-			struct alternate_object_database *alt;
-			/* 43 = 40-byte + 2 '/' + terminating NUL */
-			int pfxlen = cp - last;
-			int entlen = pfxlen + 43;
-
-			if (*last != '/' && relative_base) {
-				/* Relative alt-odb */
-				if (base_len < 0)
-					base_len = strlen(relative_base) + 1;
-				entlen += base_len;
-				pfxlen += base_len;
-			}
-			ent = xmalloc(sizeof(*ent) + entlen);
-
-			if (*last != '/' && relative_base) {
-				memcpy(ent->base, relative_base, base_len - 1);
-				ent->base[base_len - 1] = '/';
-				memcpy(ent->base + base_len,
-				       last, cp - last);
-			}
-			else
-				memcpy(ent->base, last, pfxlen);
-
-			ent->name = ent->base + pfxlen + 1;
-			ent->base[pfxlen + 3] = '/';
-			ent->base[pfxlen] = ent->base[entlen-1] = 0;
-
-			/* Detect cases where alternate disappeared */
-			if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) {
-				error("object directory %s does not exist; "
-				      "check .git/objects/info/alternates.",
-				      ent->base);
-				goto bad;
-			}
-			ent->base[pfxlen] = '/';
-
-			/* Prevent the common mistake of listing the same
-			 * thing twice, or object directory itself.
-			 */
-			for (alt = alt_odb_list; alt; alt = alt->next)
-				if (!memcmp(ent->base, alt->base, pfxlen))
-					goto bad;
-			if (!memcmp(ent->base, objdir, pfxlen)) {
-			bad:
-				free(ent);
-			}
-			else {
-				*alt_odb_tail = ent;
-				alt_odb_tail = &(ent->next);
-				ent->next = NULL;
+			if ((*last != '/') && depth) {
+				error("%s: ignoring relative alternate object store %s",
+						relative_base, last);
+			} else {
+				link_alt_odb_entry(last, cp - last,
+						relative_base, depth);
 			}
 		}
 		while (cp < ep && *cp == sep)
@@ -311,23 +339,14 @@ static void link_alt_odb_entries(const c
 	}
 }
 
-void prepare_alt_odb(void)
+static void read_info_alternates(const char * relative_base, int depth)
 {
-	char path[PATH_MAX];
 	char *map;
-	int fd;
 	struct stat st;
-	char *alt;
-
-	alt = getenv(ALTERNATE_DB_ENVIRONMENT);
-	if (!alt) alt = "";
-
-	if (alt_odb_tail)
-		return;
-	alt_odb_tail = &alt_odb_list;
-	link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL);
+	char path[PATH_MAX];
+	int fd;
 
-	sprintf(path, "%s/info/alternates", get_object_directory());
+	sprintf(path, "%s/info/alternates", relative_base);
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
 		return;
@@ -340,11 +359,26 @@ void prepare_alt_odb(void)
 	if (map == MAP_FAILED)
 		return;
 
-	link_alt_odb_entries(map, map + st.st_size, '\n',
-			     get_object_directory());
+	link_alt_odb_entries(map, map + st.st_size, '\n', relative_base, depth);
+
 	munmap(map, st.st_size);
 }
 
+void prepare_alt_odb(void)
+{
+	char *alt;
+
+	alt = getenv(ALTERNATE_DB_ENVIRONMENT);
+	if (!alt) alt = "";
+
+	if (alt_odb_tail)
+		return;
+	alt_odb_tail = &alt_odb_list;
+	link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0);
+
+	read_info_alternates(get_object_directory(), 0);
+}
+
 static char *find_sha1_file(const unsigned char *sha1, struct stat *st)
 {
 	char *name = sha1_file_name(sha1);
-- 
1.3.1.g6ef7

^ permalink raw reply related

* [PATCH] test case for transitive info/alternates
From: Martin Waitz @ 2006-05-07 18:19 UTC (permalink / raw)
  To: git

Signed-off-by: Martin Waitz <tali@admingilde.org>

---

 t/t5710-info-alternate.sh |  105 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 105 insertions(+), 0 deletions(-)
 create mode 100755 t/t5710-info-alternate.sh

47d59f8b0c26226a40344673ecd9e6255a576b98
diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh
new file mode 100755
index 0000000..097d037
--- /dev/null
+++ b/t/t5710-info-alternate.sh
@@ -0,0 +1,105 @@
+#!/bin/sh
+#
+# Copyright (C) 2006 Martin Waitz <tali@admingilde.org>
+#
+
+test_description='test transitive info/alternate entries'
+. ./test-lib.sh
+
+# test that a file is not reachable in the current repository
+# but that it is after creating a info/alternate entry
+reachable_via() {
+	alternate="$1"
+	file="$2"
+	if git cat-file -e "HEAD:$file"; then return 1; fi
+	echo "$alternate" >> .git/objects/info/alternate
+	git cat-file -e "HEAD:$file"
+}
+
+test_valid_repo() {
+	git fsck-objects --full > fsck.log &&
+	test `wc -l < fsck.log` = 0
+}
+
+base_dir=`pwd`
+
+test_expect_success 'preparing first repository' \
+'test_create_repo A && cd A &&
+echo "Hello World" > file1 &&
+git add file1 &&
+git commit -m "Initial commit" file1 &&
+git repack -a -d &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'preparing second repository' \
+'git clone -l -s A B && cd B &&
+echo "foo bar" > file2 &&
+git add file2 &&
+git commit -m "next commit" file2 &&
+git repack -a -d -l &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_success 'preparing third repository' \
+'git clone -l -s B C && cd C &&
+echo "Goodbye, cruel world" > file3 &&
+git add file3 &&
+git commit -m "one more" file3 &&
+git repack -a -d -l &&
+git prune'
+
+cd "$base_dir"
+
+test_expect_failure 'creating too deep nesting' \
+'git clone -l -s C D &&
+git clone -l -s D E &&
+git clone -l -s E F &&
+git clone -l -s F G &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'validity of third repository' \
+'cd C &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'validity of fourth repository' \
+'cd D &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'breaking of loops' \
+"echo '$base_dir/B/.git/objects' >> '$base_dir'/A/.git/objects/info/alternates&&
+cd C &&
+test_valid_repo"
+
+cd "$base_dir"
+
+test_expect_failure 'that info/alternates is neccessary' \
+'cd C &&
+rm .git/objects/info/alternates &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_success 'that relative alternate is possible for current dir' \
+'cd C &&
+echo "../../../B/.git/objects" > .git/objects/info/alternates &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_expect_failure 'that relative alternate is only possible for current dir' \
+'cd D &&
+test_valid_repo'
+
+cd "$base_dir"
+
+test_done
+
-- 
1.3.1.g6ef7

^ permalink raw reply related

* [PATCH] clone: don't clone the info/alternates file
From: Martin Waitz @ 2006-05-07 18:19 UTC (permalink / raw)
  To: git

Now that the cloned alternates file is parsed, too we don't need to
copy it into our new repository, we just reference it.

Signed-off-by: Martin Waitz <tali@admingilde.org>

---

 git-clone.sh |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

4dc26b7a15c0778459f2ccf85aad1c03d1b3a3cc
diff --git a/git-clone.sh b/git-clone.sh
index b785247..227245c 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -261,11 +261,7 @@ yes,yes)
 	    ;;
 	yes)
 	    mkdir -p "$GIT_DIR/objects/info"
-	    {
-		test -f "$repo/objects/info/alternates" &&
-		cat "$repo/objects/info/alternates";
-		echo "$repo/objects"
-	    } >>"$GIT_DIR/objects/info/alternates"
+	    echo "$repo/objects" >> "$GIT_DIR/objects/info/alternates"
 	    ;;
 	esac
 	git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD"
-- 
1.3.1.g6ef7

^ permalink raw reply related

* Re: [PATCH] Transitively read alternatives
From: Jakub Narebski @ 2006-05-07 18:28 UTC (permalink / raw)
  To: git
In-Reply-To: <20060507181920.GC23738@admingilde.org>

Martin Waitz wrote:

> When adding an alternate object store then add entries from its
> info/alternates files, too.
> Relative entries are only allowed in the current repository.
> Loops and duplicate alternates through multiple repositories are ignored.
> Just to be sure that nothing breaks it is not allow to build deep
> nesting levels using info/alternates.

> +     if (depth > 5) {
> +             error("%s: ignoring alternate object stores, nesting too deep.",
> +                             relative_base);
> +             return;
> +     }

Please, no magic numbers. Use preprocesor "constants" for that.

-- 
Jakub Narebski
Warsaw, Poland

^ permalink raw reply

* Re: symlinks
From: Yakov Lerner @ 2006-05-07 19:28 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: git
In-Reply-To: <Pine.LNX.4.64.0605071104230.3718@g5.osdl.org>

On 5/7/06, Linus Torvalds <torvalds@osdl.org> wrote:
>
>
> On Sun, 7 May 2006, Yakov Lerner wrote:
> >
> > I have a project that makes heavy use of symlinks in the source tree.
> > I added it to git, then cloned the repository, and all symlinks were
> > converted to plain files. What am I missing to preserve symlinks ?
>
> You're not missing anything, it sounds like a bug. What did you use to
> clone, and what version? It definitely doesn't happen for me:
>
>        mkdir symlink
>        cd symlink/
>        git-init-db
>        ln -s unknown new-link
>        ls -l
>        git add new-link
>        git commit
>
>        cd
>        git clone symlink symlink2
>        cd symlink2/
>        ls -l
>
> shows that the symlink was preserved.

Yes, I see now it's not git problem. I suspect
I just incorrectly copied the files into git-init-db directory,
something like 'cp -r' instead of 'cp -a' or tar/cpio. Sorry I'm
new to git.

Thanks
Yakov

^ permalink raw reply

* [patch] munmap-before-rename, cygwin need
From: Yakov Lerner @ 2006-05-07 19:58 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 2749 bytes --]

I found that mmap() works on cygwin, but needs a patch.
On Cygwin, rename() fails if target file has active mmap().
The patch below adds  munmap() before rename().

If you excuse me for posting not in git-generated format
(I did not yet completely make git working on my cygwin).
I'm adding the copy as attachment, I'm afraid the mailer
may interfere with spaces ?

Yakov Lerner

Makefile     |    5 +++++
cache.h      |    1 +
index.c      |    3 +++
read-cache.c |   14 ++++++++++++++

--- Makefile.000 2006-05-07 22:32:04.000000000 +0300
+++ Makefile 2006-05-07 22:30:38.000000000 +0300
@@ -46,6 +46,9 @@
#
# Define NO_MMAP if you want to avoid mmap.
#
+# Define MUMNAP_BEFORE_RENAME if munmap() on target file is required
+# before rename().
+#
# Define WITH_OWN_SUBPROCESS_PY if you want to use with python 2.3.
#
# Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
@@ -270,6 +273,8 @@
# NO_MMAP = YesPlease
NO_IPV6 = YesPlease
X = .exe
+ MUMNAP_BEFORE_RENAME = YesPlease
+ NO_SOCKADDR_STORAGE = YesPlease
endif
ifeq ($(uname_S),FreeBSD)
NEEDS_LIBICONV = YesPlease
--- cache.h.000 2006-05-02 11:35:50.000000000 +0300
+++ cache.h 2006-05-02 11:33:34.000000000 +0300
@@ -140,6 +140,7 @@

/* Initialize and use the cache information */
extern int read_cache(void);
+extern void unmap_cache(void);
extern int write_cache(int newfd, struct cache_entry **cache, int entries);
extern int cache_name_pos(const char *name, int namelen);
#define ADD_CACHE_OK_TO_ADD 1 /* Ok to add */
--- read-cache.c.000 2006-05-07 22:33:42.000000000 +0300
+++ read-cache.c 2006-05-02 11:32:56.000000000 +0300
@@ -513,6 +513,9 @@
return 0;
}

+static void *mapaddr = MAP_FAILED;
+static unsigned long mapsize;
+
int read_cache(void)
{
int fd, i;
@@ -541,6 +544,8 @@
errno = EINVAL;
if (size >= sizeof(struct cache_header) + 20)
map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ mapaddr = map;
+ mapsize = size;
}
close(fd);
if (map == MAP_FAILED)
@@ -565,10 +570,19 @@

unmap:
munmap(map, size);
+ mapaddr = MAP_FAILED;
errno = EINVAL;
die("index file corrupt");
}

+void unmap_cache(void)
+{
+ if ( mapaddr != MAP_FAILED ) {
+ munmap(mapaddr, mapsize);
+ mapaddr = MAP_FAILED;
+ }
+}
+
#define WRITE_BUFFER_SIZE 8192
static unsigned char write_buffer[WRITE_BUFFER_SIZE];
static unsigned long write_buffer_len;
--- index.c.000 2006-05-07 22:36:04.000000000 +0300
+++ index.c 2006-05-07 22:36:40.000000000 +0300
@@ -43,6 +43,9 @@
strcpy(indexfile, cf->lockfile);
i = strlen(indexfile) - 5; /* .lock */
indexfile[i] = 0;
+#ifdef MUMNAP_BEFORE_RENAME
+ unmap_cache();
+#endif
i = rename(cf->lockfile, indexfile);
cf->lockfile[0] = 0;
return i;

[-- Attachment #2: patch-munmap-before-rename --]
[-- Type: text/plain, Size: 2237 bytes --]

--- Makefile.000	2006-05-07 22:32:04.000000000 +0300
+++ Makefile	2006-05-07 22:30:38.000000000 +0300
@@ -46,6 +46,9 @@
 #
 # Define NO_MMAP if you want to avoid mmap.
 #
+# Define MUMNAP_BEFORE_RENAME if munmap() on target file is required
+# before rename().
+#
 # Define WITH_OWN_SUBPROCESS_PY if you want to use with python 2.3.
 #
 # Define NO_IPV6 if you lack IPv6 support and getaddrinfo().
@@ -270,6 +273,8 @@
 	# NO_MMAP = YesPlease
 	NO_IPV6 = YesPlease
 	X = .exe
+	MUMNAP_BEFORE_RENAME = YesPlease
+	NO_SOCKADDR_STORAGE = YesPlease
 endif
 ifeq ($(uname_S),FreeBSD)
 	NEEDS_LIBICONV = YesPlease
--- cache.h.000	2006-05-02 11:35:50.000000000 +0300
+++ cache.h	2006-05-02 11:33:34.000000000 +0300
@@ -140,6 +140,7 @@
 
 /* Initialize and use the cache information */
 extern int read_cache(void);
+extern void unmap_cache(void);
 extern int write_cache(int newfd, struct cache_entry **cache, int entries);
 extern int cache_name_pos(const char *name, int namelen);
 #define ADD_CACHE_OK_TO_ADD 1		/* Ok to add */
--- read-cache.c.000	2006-05-07 22:33:42.000000000 +0300
+++ read-cache.c	2006-05-02 11:32:56.000000000 +0300
@@ -513,6 +513,9 @@
 	return 0;
 }
 
+static void *mapaddr = MAP_FAILED;
+static unsigned long mapsize;
+
 int read_cache(void)
 {
 	int fd, i;
@@ -541,6 +544,8 @@
 		errno = EINVAL;
 		if (size >= sizeof(struct cache_header) + 20)
 			map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+		mapaddr = map;
+		mapsize = size;
 	}
 	close(fd);
 	if (map == MAP_FAILED)
@@ -565,10 +570,19 @@
 
 unmap:
 	munmap(map, size);
+	mapaddr = MAP_FAILED;
 	errno = EINVAL;
 	die("index file corrupt");
 }
 
+void unmap_cache(void)
+{
+	if ( mapaddr != MAP_FAILED ) {
+		munmap(mapaddr, mapsize);
+		mapaddr = MAP_FAILED;
+	}
+}
+
 #define WRITE_BUFFER_SIZE 8192
 static unsigned char write_buffer[WRITE_BUFFER_SIZE];
 static unsigned long write_buffer_len;
--- index.c.000	2006-05-07 22:36:04.000000000 +0300
+++ index.c	2006-05-07 22:36:40.000000000 +0300
@@ -43,6 +43,9 @@
 	strcpy(indexfile, cf->lockfile);
 	i = strlen(indexfile) - 5; /* .lock */
 	indexfile[i] = 0;
+#ifdef MUMNAP_BEFORE_RENAME
+	unmap_cache();
+#endif
 	i = rename(cf->lockfile, indexfile);
 	cf->lockfile[0] = 0;
 	return i;

^ permalink raw reply

* Re: [PATCH] Sparse fix for builtin-diff
From: Junio C Hamano @ 2006-05-07 20:43 UTC (permalink / raw)
  To: Peter Hagervall; +Cc: junkio, git
In-Reply-To: <20060507145046.GA24882@peppar.cs.umu.se>

Peter Hagervall <hager@cs.umu.se> writes:

> You gotta love sparse:
>
> builtin-diff.c:88:4: error: Just how const do you want this type to be?

LOL.

> -		const
> -			const unsigned char *tmp_u;
> +		const unsigned char *tmp_u;

I wondered how this bit snuck in, but it was like that
from the beginning, my bad.

Thanks.

^ permalink raw reply

* Re: [patch] munmap-before-rename, cygwin need
From: Junio C Hamano @ 2006-05-07 21:14 UTC (permalink / raw)
  To: Yakov Lerner; +Cc: git
In-Reply-To: <f36b08ee0605071258s7a0cb085r3f08e9981234255a@mail.gmail.com>

"Yakov Lerner" <iler.ml@gmail.com> writes:

> I found that mmap() works on cygwin, but needs a patch.
> On Cygwin, rename() fails if target file has active mmap().
> The patch below adds  munmap() before rename().

This is interesting in three counts.

 - I from time to time test Cygwin version on my day-job machine
   (W2K) and my wife's machine (XP); on both machines I usually
   have less than two weeks old Cygwin installation, and I have
   not seen the breakage.  I wonder how reproducible this is.
   Also previously people reported mmap() works for some and
   fake mmap is needed for others.  Would this patch make things
   work for everybody?

 - The part you patched is commit_index_file().  This typically
   is called just before program exit, but some callers, like
   apply.c, may want to still look at the index after calling
   it, fully aware that the changes after commit_index will not
   be written out.  Although I haven't traced the codepath fully
   in apply.c yet, unmapping would break the access to the index
   (i.e. active_cache[]).  Does apply still work with your
   patch?

 - As long as you can clear the second point, I do not see a
   particular reason to make this an option; we should be able
   to do so everywhere.

^ permalink raw reply

* Implementing branch attributes in git config
From: Pavel Roskin @ 2006-05-07 21:34 UTC (permalink / raw)
  To: git

Hello!

I have tried to implement branch attributes (more specifically, the
default for git-fetch) in git config.  It turns out that the format of
the config file is to rigid.

Minuses, underscores, colons and dots are not allowed in the section
headers and keys.  I can understand that dots should be allowed either
in the section names or in the key names, but other limitations seem
totally unnecessary.

I think a good implementation should allow any characters in the keys,
even "=", because the key can be quoted.  Section names may disallow
square brackets and dots.

Such limitations make it unpractical to use branch names in section or
key names.  I'd like to have it fixed.

The only remaining place is values.  This means that there should be
multiple entries for the same key.  While this is allowed, it seems
quite fragile and inconvenient.

In particular, git-repo-config leaves the config file locked in the
regex is wrong:

$ git-repo-config branch.fetch "master:origin" +
Invalid pattern: +
$ git-repo-config branch.fetch "master:origin" +
could not lock config file

To fix it, just add "close(fd); unlink(lock_file);" after "Invalid
pattern" in config.c.

I don't quite understand what pattern is needed to add an entry.  "foo"
seems to work fine, I don't know why.

That problem with multiple values is that they are quite fragile and
require special options to access them.  Since regex is used, dots in
the branch names need to be escaped.  Probably more escapes are needed.

Anyway, here's the preliminary patch that implements default fetch
branches.  Unfortunately, it doesn't even come close to the goal of
having per-branch attributes due to the config file limitations.

To add an entry, use

git-repo-config branch.fetch "localbranch:remotebranch" foo


Read the default fetch branch from the config file

From: Pavel Roskin <proski@gnu.org>


---

 git-fetch.sh |   21 +++++++++++++++++----
 1 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/git-fetch.sh b/git-fetch.sh
index 280f62e..a5ea92b 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -61,12 +61,25 @@ do
 	shift
 done
 
+get_config_rem_branch() {
+	fetch_branch=origin
+	cur_branch=$(expr $(git-symbolic-ref HEAD) : 'refs/heads/\(.*\)')
+	test -z "$cur_branch" && return
+	cur_branch_esc=$(echo $cur_branch | sed 's/\./\\./')
+	branch_map=$(git-repo-config --get branch.fetch "^$cur_branch_esc:")
+	test -z "$branch_map" && return
+	rem_branch=$(expr "$branch_map" : "$cur_branch_esc:\(.*\)")
+	test -z "$rem_branch" && return
+	fetch_branch="$rem_branch"
+}
+
 case "$#" in
 0)
-	test -f "$GIT_DIR/branches/origin" ||
-		test -f "$GIT_DIR/remotes/origin" ||
-			die "Where do you want to fetch from today?"
-	set origin ;;
+	get_config_rem_branch
+	test -f "$GIT_DIR/branches/$fetch_branch" ||
+		test -f "$GIT_DIR/remotes/$fetch_branch" ||
+			die "No remote branch \"$fetch_branch\""
+	set "$fetch_branch" ;;
 esac
 
 remote_nick="$1"


-- 
Regards,
Pavel Roskin

^ permalink raw reply related

* [PATCH] Release config lock if the regex is invalid
From: Pavel Roskin @ 2006-05-07 21:36 UTC (permalink / raw)
  To: git

Signed-off-by: Pavel Roskin <proski@gnu.org>
---

 config.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/config.c b/config.c
index 41066e4..61eacef 100644
--- a/config.c
+++ b/config.c
@@ -516,6 +516,8 @@ int git_config_set_multivar(const char* 
 				fprintf(stderr, "Invalid pattern: %s\n",
 					value_regex);
 				free(store.value_regex);
+				close(fd);
+				unlink(lock_file);
 				ret = 6;
 				goto out_free;
 			}

^ permalink raw reply related

* Re: Implementing branch attributes in git config
From: Junio C Hamano @ 2006-05-07 22:24 UTC (permalink / raw)
  To: Pavel Roskin; +Cc: git
In-Reply-To: <1147037659.25090.25.camel@dv>

Pavel Roskin <proski@gnu.org> writes:

> In particular, git-repo-config leaves the config file locked in the
> regex is wrong:
>
> $ git-repo-config branch.fetch "master:origin" +
> Invalid pattern: +
> $ git-repo-config branch.fetch "master:origin" +
> could not lock config file
>
> To fix it, just add "close(fd); unlink(lock_file);" after "Invalid
> pattern" in config.c.

I'd give Johannes the first refusal right to deal with this and
not touch repo-config.c myself for now, since I suspect I
tempted him enough to restructure it ;-).

> I don't quite understand what pattern is needed to add an entry.  "foo"
> seems to work fine, I don't know why.

I think the value regexp is "replace the ones that match this",
and the convention he came up with is to use "^$" to append (see
some examples in t/t1300-repo-config.sh).

In any case, Documentation/git-repo-config.txt mentions
value_regex without explaining what the semantics is.  This
needs to be fixed, probably like the attached patch.

> That problem with multiple values is that they are quite fragile and
> require special options to access them.  Since regex is used, dots in
> the branch names need to be escaped.  Probably more escapes are needed.

I have a suspicion that using regex while is more powerful and
expressive might be a mistake and it would be easier for users
(both Porcelain and end-users) to use fnmatch() patterns.

> Such limitations make it unpractical to use branch names in section or
> key names.  I'd like to have it fixed.

I thought that is what the "for blah" convention is for (BTW
"for" is not a keyword, just a convention).

Also the syntax is a bit confusing.  I initially was confused,
after looking at your example:

	[branch]
        	fetch = "localbranch:remotebranch"

that the colon separated value was a usual refspec, but it
isn't.  The LHS is the name of the current branch, and RHS is
the name of the remotes/ file, which is not a remote _branch_ at
all.  Perhaps something like this is semantically clearer, aside
from names -- I am bad at coming up with them:

	[branch]
		defaultremote = origin for master
                defaultremote = private for test

to mean, "we use remotes/origin when on master branch by
default".  Also we would want to use remote.origin.{url,fetch}
configuration item as well, so the "file existence" check you do
in this part of the patch is wrong.

>  case "$#" in
>  0)
> -	test -f "$GIT_DIR/branches/origin" ||
> -		test -f "$GIT_DIR/remotes/origin" ||
> -			die "Where do you want to fetch from today?"
> -	set origin ;;
> +	get_config_rem_branch
> +	test -f "$GIT_DIR/branches/$fetch_branch" ||
> +		test -f "$GIT_DIR/remotes/$fetch_branch" ||
> +			die "No remote branch \"$fetch_branch\""
> +	set "$fetch_branch" ;;
>  esac

We should instead let the existence check do the right thing for
"$1" when it is used; after all the default "origin" may not
exist, and I suspect we do not probably check that (or if we do
already, the above check is totally unnecessary).

I haven't thought things through but I have a suspicion that
get_config_rem_branch might belong to git-parse-remote.sh not
git-fetch.sh.

-- >8 --
diff --git a/Documentation/git-repo-config.txt b/Documentation/git-repo-config.txt
index fd44f62..660c18f 100644
--- a/Documentation/git-repo-config.txt
+++ b/Documentation/git-repo-config.txt
@@ -23,10 +23,11 @@ You can query/set/replace/unset options 
 actually the section and the key separated by a dot, and the value will be
 escaped.
 
-If you want to set/unset an option which can occur on multiple lines, you
-should provide a POSIX regex for the value. If you want to handle the lines
-*not* matching the regex, just prepend a single exclamation mark in front
-(see EXAMPLES).
+If you want to set/unset an option which can occur on multiple
+lines, a POSIX regexp `value_regex` needs to be given.  Only the
+existing values that match the regexp are updated or unset.  If
+you want to handle the lines that do *not* match the regex, just
+prepend a single exclamation mark in front (see EXAMPLES).
 
 The type specifier can be either '--int' or '--bool', which will make
 'git-repo-config' ensure that the variable(s) are of the given type and

^ permalink raw reply related

* Re: Unresolved issues #2 (shallow clone again)
From: Martin Langhoff @ 2006-05-07 23:27 UTC (permalink / raw)
  To: Sergey Vlasov; +Cc: Junio C Hamano, git
In-Reply-To: <20060507120149.40e9f749.vsu@altlinux.ru>

On 5/7/06, Sergey Vlasov <vsu@altlinux.ru> wrote:
> For linux v2.6.16:
>
> 7,3M commits-b41b04a36afebdba3b70b74f419fc7d97249bd7f.pack
>  24M commits_trees-8397f1c2a885527acd07e2caa8c95df626451493.pack
>  97M full-c7b2747a674ff55cb4a59dabebe419f191e360df.pack

With this pack arrangement, do you get any noticeable difference in
walking commits? How about walking commits+trees with git-log <path> ?

I wonder whether segregating packs by object type would make things better...

cheers,



martin

^ 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