git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
@ 2009-09-07 14:11 Nick Edelen
  2009-09-27 22:44 ` Nick Edelen
  2009-10-19 20:31 ` Nick Edelen
  0 siblings, 2 replies; 8+ messages in thread
From: Nick Edelen @ 2009-09-07 14:11 UTC (permalink / raw)
  To: Nick Edelen, Junio C Hamano, Nicolas Pitre, Johannes Schindelin,
	Sam Vilain

Adds support for graft commits in rev-cache (w/ test), and slightly alters
graft mechanism.  Before, parse_commit() checked the graft list on every
commit.  Now register_commit_graft() preemptively loads graft commits into
memory, and sets a new 'graft' flag in the object.  This allows awareness of
the commits' medical history without searching a (normally private) array upon
each commit.

Signed-off-by: Nick Edelen <sirnot@gmail.com>

---
THE PATCH THAT NEVER WAS!  (sorry about the wack numbering; the change isn't
very big and it seemed silly to escalate the version)

 builtin-rev-cache.c       |   14 ++++++++++++--
 commit.c                  |   25 +++++++++++++++++++++++--
 object.h                  |    3 ++-
 rev-cache.c               |   32 ++++++++++++++++++++++++++++++++
 t/t6017-rev-cache-list.sh |    6 ++++++
 5 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/builtin-rev-cache.c b/builtin-rev-cache.c
index 4c1766d..b36bc39 100644
--- a/builtin-rev-cache.c
+++ b/builtin-rev-cache.c
@@ -102,8 +102,18 @@ static int test_rev_list(int argc, const char *argv[])
 			flags ^= UNINTERESTING;
 		else if (!strcmp(argv[i], "--objects"))
 			revs.tree_objects = revs.blob_objects = 1;
-		else
-			handle_revision_arg(argv[i], &revs, flags, 1);
+		else {
+			struct commit_graft graft;
+
+			if (argv[i][0] == ':') {
+				handle_revision_arg(argv[i] + 1, &revs, flags, 1);
+
+				hashcpy(graft.sha1, revs.pending.objects[revs.pending.nr - 1].item->sha1);
+				graft.nr_parent = -1;
+				register_commit_graft(&graft, 0);
+			} else
+				handle_revision_arg(argv[i], &revs, flags, 1);
+		}
 	}
 
 	setup_revisions(0, 0, &revs, 0);
diff --git a/commit.c b/commit.c
index b7485c4..8429f69 100644
--- a/commit.c
+++ b/commit.c
@@ -99,6 +99,7 @@ static int commit_graft_pos(const unsigned char *sha1)
 
 int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 {
+	struct commit *commit;
 	int pos = commit_graft_pos(graft->sha1);
 
 	if (0 <= pos) {
@@ -123,6 +124,12 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 			(commit_graft_nr - pos - 1) *
 			sizeof(*commit_graft));
 	commit_graft[pos] = graft;
+
+	commit = lookup_commit(graft->sha1);
+	commit->object.graft = 1;
+	commit->object.parsed = 0;
+	parse_commit(commit); /* in case commit was already parsed */
+
 	return 0;
 }
 
@@ -221,6 +228,7 @@ int write_shallow_commits(int fd, int use_pack_protocol)
 
 int unregister_shallow(const unsigned char *sha1)
 {
+	struct commit *commit;
 	int pos = commit_graft_pos(sha1);
 	if (pos < 0)
 		return -1;
@@ -229,6 +237,12 @@ int unregister_shallow(const unsigned char *sha1)
 				sizeof(struct commit_graft *)
 				* (commit_graft_nr - pos - 1));
 	commit_graft_nr--;
+
+	commit = lookup_commit(sha1);
+	commit->object.graft = 0;
+	commit->object.parsed = 0;
+	parse_commit(commit);
+
 	return 0;
 }
 
@@ -255,7 +269,11 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 	while (pop_commit(pptr))
 		; /* clear anything from cache */
 
-	graft = lookup_commit_graft(item->object.sha1);
+	if (item->object.graft)
+		graft = lookup_commit_graft(item->object.sha1);
+	else
+		graft = 0;
+
 	while (bufptr + 48 < tail && !memcmp(bufptr, "parent ", 7)) {
 		struct commit *new_parent;
 
@@ -283,7 +301,10 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 				continue;
 			pptr = &commit_list_insert(new_parent, pptr)->next;
 		}
-	}
+		item->object.graft = 1;
+	} else
+		item->object.graft = 0;
+
 	item->date = parse_commit_date(bufptr, tail);
 
 	return 0;
diff --git a/object.h b/object.h
index 89dd0c4..f848e0f 100644
--- a/object.h
+++ b/object.h
@@ -22,7 +22,7 @@ struct object_array {
 };
 
 #define TYPE_BITS   3
-#define FLAG_BITS  27
+#define FLAG_BITS  26
 
 /*
  * The object type is stored in 3 bits.
@@ -30,6 +30,7 @@ struct object_array {
 struct object {
 	unsigned parsed : 1;
 	unsigned used : 1;
+	unsigned graft : 1;
 	unsigned type : TYPE_BITS;
 	unsigned flags : FLAG_BITS;
 	unsigned char sha1[20];
diff --git a/rev-cache.c b/rev-cache.c
index 3595f66..84305e9 100644
--- a/rev-cache.c
+++ b/rev-cache.c
@@ -663,9 +663,41 @@ static int traverse_cache_slice_1(struct rc_slice_header *head, unsigned char *m
 			}
 		} else if (!ipath_nr && co->date <= date)
 			slop--;
+		else if (!ipath_nr && !upath_nr)
+			break;
 		else
 			slop = SLOP;
 
+		/* before opening further topo-relations, check if the parenting has had medical attention */
+		if (obj->graft) {
+			struct commit_list *list;
+
+			parse_commit(co);
+			obj->flags &= ~FACE_VALUE;
+			last_objects[path] = 0;
+
+			/* we're only interested in its indirect influence */
+			for (list = co->parents; list; list = list->next) {
+				struct rc_index_entry *iep;
+				struct object *po = &list->item->object;
+
+				iep = search_index(po->sha1);
+				if (!iep || hashcmp(idx_caches + 20 * iep->cache_index, head->sha1)) {
+					if (!(obj->flags & UNINTERESTING) && !(po->flags & UNINTERESTING))
+						ioutside = 1;
+				}
+			}
+
+			/* an abrupt end */
+			myworkp = &commit_list_insert(co, myworkp)->next;
+			if (entry->uninteresting)
+				upath_nr--;
+			else
+				ipath_nr--;
+			paths[path] = 0;
+			continue;
+		}
+
 		/* open parents */
 		if (entry->merge_nr) {
 			int j, off = index + sizeof(struct rc_object_entry_ondisk);
diff --git a/t/t6017-rev-cache-list.sh b/t/t6017-rev-cache-list.sh
index 3286560..6ada7ac 100755
--- a/t/t6017-rev-cache-list.sh
+++ b/t/t6017-rev-cache-list.sh
@@ -92,6 +92,7 @@ git-rev-list --topo-order HEAD --not HEAD~2 >proper_commit_list_limited2
 git-rev-list --topo-order HEAD >proper_commit_list
 git-rev-list --objects HEAD >proper_object_list
 git-rev-list HEAD --max-age=$min_date --min-age=$max_date >proper_list_date_limited
+git-rev-cache test HEAD :HEAD~2 >proper_shallow_list
 
 cache_sha1=`git-rev-cache add HEAD 2>output.err`
 
@@ -252,4 +253,9 @@ test_expect_success 'test --ignore-size function in fuse' '
 	test -e .git/rev-cache/$cache_sha1
 '
 
+test_expect_success 'check graft handling' '
+	git-rev-cache test HEAD :HEAD~2 >list
+	test_cmp list proper_shallow_list
+'
+
 test_done
-- 
tg: (3a6aad2..) t/revcache/graft (depends on: t/revcache/names)

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
  2009-09-07 14:11 [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism Nick Edelen
@ 2009-09-27 22:44 ` Nick Edelen
  2009-09-29 16:34   ` Shawn O. Pearce
  2009-10-19 20:31 ` Nick Edelen
  1 sibling, 1 reply; 8+ messages in thread
From: Nick Edelen @ 2009-09-27 22:44 UTC (permalink / raw)
  To: Nick Edelen, Junio C Hamano, Nicolas Pitre, Johannes Schindelin,
	Sam Vilain

Adds support for graft commits in rev-cache (w/ test), and slightly alters
graft mechanism.  Before, parse_commit() checked the graft list on every
commit.  Now register_commit_graft() preemptively loads graft commits into
memory, and sets a new 'graft' flag in the object.  This allows awareness of
the commits' medical history without searching a (normally private) array upon
each commit.

Signed-off-by: Nick Edelen <sirnot@gmail.com>

---
In my infinite wisdom, I had forgotten to actually load the graft file in the
mechanism change.  This rectifies the error, fixing test t6001-rev-list-graft.
(this was the only test that I found rev-cache to break; if you find others
please tell me!)

  builtin-rev-cache.c       |   14 ++++++++++++--
  commit.c                  |   27 +++++++++++++++++++++++++--
  object.h                  |    3 ++-
  rev-cache.c               |   32 ++++++++++++++++++++++++++++++++
  t/t6017-rev-cache-list.sh |    6 ++++++
  5 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/builtin-rev-cache.c b/builtin-rev-cache.c
index 4c1766d..b36bc39 100644
--- a/builtin-rev-cache.c
+++ b/builtin-rev-cache.c
@@ -102,8 +102,18 @@ static int test_rev_list(int argc, const char *argv[])
  			flags ^= UNINTERESTING;
  		else if (!strcmp(argv[i], "--objects"))
  			revs.tree_objects = revs.blob_objects = 1;
-		else
-			handle_revision_arg(argv[i], &revs, flags, 1);
+		else {
+			struct commit_graft graft;
+
+			if (argv[i][0] == ':') {
+				handle_revision_arg(argv[i] + 1, &revs, flags, 1);
+
+				hashcpy(graft.sha1, revs.pending.objects[revs.pending.nr - 1].item->sha1);
+				graft.nr_parent = -1;
+				register_commit_graft(&graft, 0);
+			} else
+				handle_revision_arg(argv[i], &revs, flags, 1);
+		}
  	}

  	setup_revisions(0, 0, &revs, 0);
diff --git a/commit.c b/commit.c
index b7485c4..dd0e3ca 100644
--- a/commit.c
+++ b/commit.c
@@ -99,6 +99,7 @@ static int commit_graft_pos(const unsigned char *sha1)

  int register_commit_graft(struct commit_graft *graft, int ignore_dups)
  {
+	struct commit *commit;
  	int pos = commit_graft_pos(graft->sha1);

  	if (0 <= pos) {
@@ -123,6 +124,12 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
  			(commit_graft_nr - pos - 1) *
  			sizeof(*commit_graft));
  	commit_graft[pos] = graft;
+
+	commit = lookup_commit(graft->sha1);
+	commit->object.graft = 1;
+	commit->object.parsed = 0;
+	parse_commit(commit); /* in case commit was already parsed */
+
  	return 0;
  }

@@ -221,6 +228,7 @@ int write_shallow_commits(int fd, int use_pack_protocol)

  int unregister_shallow(const unsigned char *sha1)
  {
+	struct commit *commit;
  	int pos = commit_graft_pos(sha1);
  	if (pos < 0)
  		return -1;
@@ -229,6 +237,12 @@ int unregister_shallow(const unsigned char *sha1)
  				sizeof(struct commit_graft *)
  				* (commit_graft_nr - pos - 1));
  	commit_graft_nr--;
+
+	commit = lookup_commit(sha1);
+	commit->object.graft = 0;
+	commit->object.parsed = 0;
+	parse_commit(commit);
+
  	return 0;
  }

@@ -255,7 +269,13 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
  	while (pop_commit(pptr))
  		; /* clear anything from cache */

-	graft = lookup_commit_graft(item->object.sha1);
+	/* make sure .graft flag is initialized */
+	prepare_commit_graft();
+	if (item->object.graft)
+		graft = lookup_commit_graft(item->object.sha1);
+	else
+		graft = 0;
+
  	while (bufptr + 48 < tail && !memcmp(bufptr, "parent ", 7)) {
  		struct commit *new_parent;

@@ -283,7 +303,10 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
  				continue;
  			pptr = &commit_list_insert(new_parent, pptr)->next;
  		}
-	}
+		item->object.graft = 1;
+	} else
+		item->object.graft = 0;
+
  	item->date = parse_commit_date(bufptr, tail);

  	return 0;
diff --git a/object.h b/object.h
index 89dd0c4..f848e0f 100644
--- a/object.h
+++ b/object.h
@@ -22,7 +22,7 @@ struct object_array {
  };

  #define TYPE_BITS   3
-#define FLAG_BITS  27
+#define FLAG_BITS  26

  /*
   * The object type is stored in 3 bits.
@@ -30,6 +30,7 @@ struct object_array {
  struct object {
  	unsigned parsed : 1;
  	unsigned used : 1;
+	unsigned graft : 1;
  	unsigned type : TYPE_BITS;
  	unsigned flags : FLAG_BITS;
  	unsigned char sha1[20];
diff --git a/rev-cache.c b/rev-cache.c
index 6c96297..f7b1cd2 100644
--- a/rev-cache.c
+++ b/rev-cache.c
@@ -664,9 +664,41 @@ static int traverse_cache_slice_1(struct rc_slice_header *head, unsigned char *m
  			}
  		} else if (!ipath_nr && co->date <= date)
  			slop--;
+		else if (!ipath_nr && !upath_nr)
+			break;
  		else
  			slop = SLOP;

+		/* before opening further topo-relations, check if the parenting has had medical attention */
+		if (obj->graft) {
+			struct commit_list *list;
+
+			parse_commit(co);
+			obj->flags &= ~FACE_VALUE;
+			last_objects[path] = 0;
+
+			/* we're only interested in its indirect influence */
+			for (list = co->parents; list; list = list->next) {
+				struct rc_index_entry *iep;
+				struct object *po = &list->item->object;
+
+				iep = search_index(po->sha1);
+				if (!iep || hashcmp(idx_caches + 20 * iep->cache_index, head->sha1)) {
+					if (!(obj->flags & UNINTERESTING) && !(po->flags & UNINTERESTING))
+						ioutside = 1;
+				}
+			}
+
+			/* an abrupt end */
+			myworkp = &commit_list_insert(co, myworkp)->next;
+			if (entry->uninteresting)
+				upath_nr--;
+			else
+				ipath_nr--;
+			paths[path] = 0;
+			continue;
+		}
+
  		/* open parents */
  		if (entry->merge_nr) {
  			int j, off = index + sizeof(struct rc_object_entry_ondisk);
diff --git a/t/t6017-rev-cache-list.sh b/t/t6017-rev-cache-list.sh
index 3286560..6ada7ac 100755
--- a/t/t6017-rev-cache-list.sh
+++ b/t/t6017-rev-cache-list.sh
@@ -92,6 +92,7 @@ git-rev-list --topo-order HEAD --not HEAD~2 >proper_commit_list_limited2
  git-rev-list --topo-order HEAD >proper_commit_list
  git-rev-list --objects HEAD >proper_object_list
  git-rev-list HEAD --max-age=$min_date --min-age=$max_date >proper_list_date_limited
+git-rev-cache test HEAD :HEAD~2 >proper_shallow_list

  cache_sha1=`git-rev-cache add HEAD 2>output.err`

@@ -252,4 +253,9 @@ test_expect_success 'test --ignore-size function in fuse' '
  	test -e .git/rev-cache/$cache_sha1
  '

+test_expect_success 'check graft handling' '
+	git-rev-cache test HEAD :HEAD~2 >list
+	test_cmp list proper_shallow_list
+'
+
  test_done
-- 
tg: (ceb0b39..) t/revcache/graft (depends on: t/revcache/names)

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
  2009-09-27 22:44 ` Nick Edelen
@ 2009-09-29 16:34   ` Shawn O. Pearce
  2009-09-30  8:00     ` Chris Johnsen
  0 siblings, 1 reply; 8+ messages in thread
From: Shawn O. Pearce @ 2009-09-29 16:34 UTC (permalink / raw)
  To: Nick Edelen
  Cc: Junio C Hamano, Nicolas Pitre, Johannes Schindelin, Sam Vilain,
	Michael J Gruber, Jeff King, Andreas Ericsson, Christian Couder,
	git

Nick Edelen <sirnot@gmail.com> wrote:
> Adds support for graft commits in rev-cache (w/ test), and slightly alters
> graft mechanism.  Before, parse_commit() checked the graft list on every
> commit.  Now register_commit_graft() preemptively loads graft commits into
> memory, and sets a new 'graft' flag in the object.  This allows awareness of
> the commits' medical history without searching a (normally private) array upon
> each commit.
...
> diff --git a/builtin-rev-cache.c b/builtin-rev-cache.c
> index 4c1766d..b36bc39 100644

This doesn't apply against ne/rev-cache^, and I don't have the
blobs in my repostiory.  So I'm dropping this patch and will wait
for a resend of the series or something...

-- 
Shawn.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
  2009-09-29 16:34   ` Shawn O. Pearce
@ 2009-09-30  8:00     ` Chris Johnsen
  0 siblings, 0 replies; 8+ messages in thread
From: Chris Johnsen @ 2009-09-30  8:00 UTC (permalink / raw)
  To: Shawn O. Pearce
  Cc: Nick Edelen, Junio C Hamano, Nicolas Pitre, Johannes Schindelin,
	Sam Vilain, Michael J Gruber, Jeff King, Andreas Ericsson,
	Christian Couder, git

On 2009 Sep 29, at 11:34, Shawn O. Pearce wrote:
> Nick Edelen <sirnot@gmail.com> wrote:
>> diff --git a/builtin-rev-cache.c b/builtin-rev-cache.c
>> index 4c1766d..b36bc39 100644
>
> This doesn't apply against ne/rev-cache^, and I don't have the
> blobs in my repostiory.  So I'm dropping this patch and will wait
> for a resend of the series or something...

It appears that the patch suffers from "format=flowed" whitespace
mangling. This caused the context lines to have an extra leading
space character.

After running a ham-fisted "sed -e 's/^  / /'" over the patch,
'git am' was able to apply it to ne/rev-cache^ (d05c9be9fa) even
though one of the referenced blobs (6c96297; rev-cache.c) was missing.

-- 
Chris

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
  2009-09-07 14:11 [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism Nick Edelen
  2009-09-27 22:44 ` Nick Edelen
@ 2009-10-19 20:31 ` Nick Edelen
  2009-10-21  9:15   ` Thomas Rast
  1 sibling, 1 reply; 8+ messages in thread
From: Nick Edelen @ 2009-10-19 20:31 UTC (permalink / raw)
  To: Nick Edelen, Junio C Hamano, Nicolas Pitre, Johannes Schindelin,
	Sam Vilain, Micha

Adds support for graft commits in rev-cache (w/ test), and slightly alters
graft mechanism.  Before, parse_commit() checked the graft list on every
commit.  Now register_commit_graft() preemptively loads graft commits into
memory, and sets a new 'graft' flag in the object.  This allows awareness of
the commits' medical history without searching a (normally private) array upon
each commit.

Signed-off-by: Nick Edelen <sirnot@gmail.com>

---
fixed bug in mechanism alteration, which was causing test t6001 to fail.

 builtin-rev-cache.c       |   14 ++++++++++++--
 commit.c                  |   27 +++++++++++++++++++++++++--
 object.h                  |    3 ++-
 rev-cache.c               |   32 ++++++++++++++++++++++++++++++++
 t/t6017-rev-cache-list.sh |    6 ++++++
 5 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/builtin-rev-cache.c b/builtin-rev-cache.c
index 4c1766d..b36bc39 100644
--- a/builtin-rev-cache.c
+++ b/builtin-rev-cache.c
@@ -102,8 +102,18 @@ static int test_rev_list(int argc, const char *argv[])
 			flags ^= UNINTERESTING;
 		else if (!strcmp(argv[i], "--objects"))
 			revs.tree_objects = revs.blob_objects = 1;
-		else
-			handle_revision_arg(argv[i], &revs, flags, 1);
+		else {
+			struct commit_graft graft;
+
+			if (argv[i][0] == ':') {
+				handle_revision_arg(argv[i] + 1, &revs, flags, 1);
+
+				hashcpy(graft.sha1, revs.pending.objects[revs.pending.nr - 1].item->sha1);
+				graft.nr_parent = -1;
+				register_commit_graft(&graft, 0);
+			} else
+				handle_revision_arg(argv[i], &revs, flags, 1);
+		}
 	}
 
 	setup_revisions(0, 0, &revs, 0);
diff --git a/commit.c b/commit.c
index 61d83c6..c227748 100644
--- a/commit.c
+++ b/commit.c
@@ -99,6 +99,7 @@ static int commit_graft_pos(const unsigned char *sha1)
 
 int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 {
+	struct commit *commit;
 	int pos = commit_graft_pos(graft->sha1);
 
 	if (0 <= pos) {
@@ -123,6 +124,12 @@ int register_commit_graft(struct commit_graft *graft, int ignore_dups)
 			(commit_graft_nr - pos - 1) *
 			sizeof(*commit_graft));
 	commit_graft[pos] = graft;
+
+	commit = lookup_commit(graft->sha1);
+	commit->object.graft = 1;
+	commit->object.parsed = 0;
+	parse_commit(commit); /* in case commit was already parsed */
+
 	return 0;
 }
 
@@ -221,6 +228,7 @@ int write_shallow_commits(int fd, int use_pack_protocol)
 
 int unregister_shallow(const unsigned char *sha1)
 {
+	struct commit *commit;
 	int pos = commit_graft_pos(sha1);
 	if (pos < 0)
 		return -1;
@@ -229,6 +237,12 @@ int unregister_shallow(const unsigned char *sha1)
 				sizeof(struct commit_graft *)
 				* (commit_graft_nr - pos - 1));
 	commit_graft_nr--;
+
+	commit = lookup_commit(sha1);
+	commit->object.graft = 0;
+	commit->object.parsed = 0;
+	parse_commit(commit);
+
 	return 0;
 }
 
@@ -255,7 +269,13 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 	while (pop_commit(pptr))
 		; /* clear anything from cache */
 
-	graft = lookup_commit_graft(item->object.sha1);
+	/* make sure .graft flag is initialized */
+	prepare_commit_graft();
+	if (item->object.graft)
+		graft = lookup_commit_graft(item->object.sha1);
+	else
+		graft = 0;
+
 	while (bufptr + 48 < tail && !memcmp(bufptr, "parent ", 7)) {
 		struct commit *new_parent;
 
@@ -283,7 +303,10 @@ int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size)
 				continue;
 			pptr = &commit_list_insert(new_parent, pptr)->next;
 		}
-	}
+		item->object.graft = 1;
+	} else
+		item->object.graft = 0;
+
 	item->date = parse_commit_date(bufptr, tail);
 
 	return 0;
diff --git a/object.h b/object.h
index 89dd0c4..f848e0f 100644
--- a/object.h
+++ b/object.h
@@ -22,7 +22,7 @@ struct object_array {
 };
 
 #define TYPE_BITS   3
-#define FLAG_BITS  27
+#define FLAG_BITS  26
 
 /*
  * The object type is stored in 3 bits.
@@ -30,6 +30,7 @@ struct object_array {
 struct object {
 	unsigned parsed : 1;
 	unsigned used : 1;
+	unsigned graft : 1;
 	unsigned type : TYPE_BITS;
 	unsigned flags : FLAG_BITS;
 	unsigned char sha1[20];
diff --git a/rev-cache.c b/rev-cache.c
index 6c96297..f7b1cd2 100644
--- a/rev-cache.c
+++ b/rev-cache.c
@@ -664,9 +664,41 @@ static int traverse_cache_slice_1(struct rc_slice_header *head, unsigned char *m
 			}
 		} else if (!ipath_nr && co->date <= date)
 			slop--;
+		else if (!ipath_nr && !upath_nr)
+			break;
 		else
 			slop = SLOP;
 
+		/* before opening further topo-relations, check if the parenting has had medical attention */
+		if (obj->graft) {
+			struct commit_list *list;
+
+			parse_commit(co);
+			obj->flags &= ~FACE_VALUE;
+			last_objects[path] = 0;
+
+			/* we're only interested in its indirect influence */
+			for (list = co->parents; list; list = list->next) {
+				struct rc_index_entry *iep;
+				struct object *po = &list->item->object;
+
+				iep = search_index(po->sha1);
+				if (!iep || hashcmp(idx_caches + 20 * iep->cache_index, head->sha1)) {
+					if (!(obj->flags & UNINTERESTING) && !(po->flags & UNINTERESTING))
+						ioutside = 1;
+				}
+			}
+
+			/* an abrupt end */
+			myworkp = &commit_list_insert(co, myworkp)->next;
+			if (entry->uninteresting)
+				upath_nr--;
+			else
+				ipath_nr--;
+			paths[path] = 0;
+			continue;
+		}
+
 		/* open parents */
 		if (entry->merge_nr) {
 			int j, off = index + sizeof(struct rc_object_entry_ondisk);
diff --git a/t/t6017-rev-cache-list.sh b/t/t6017-rev-cache-list.sh
index f0f3bcf..3e16949 100755
--- a/t/t6017-rev-cache-list.sh
+++ b/t/t6017-rev-cache-list.sh
@@ -92,6 +92,7 @@ git-rev-list --topo-order HEAD --not HEAD~2 >proper_commit_list_limited2
 git-rev-list --topo-order HEAD >proper_commit_list
 git-rev-list --objects HEAD >proper_object_list
 git-rev-list HEAD --max-age=$min_date --min-age=$max_date >proper_list_date_limited
+git-rev-cache test HEAD :HEAD~2 >proper_shallow_list 2>/dev/null
 
 cache_sha1=`git-rev-cache add HEAD 2>output.err`
 
@@ -252,4 +253,9 @@ test_expect_success 'test --ignore-size function in fuse' '
 	test -e .git/rev-cache/$cache_sha1
 '
 
+test_expect_success 'check graft handling' '
+	git-rev-cache test HEAD :HEAD~2 >list
+	test_cmp list proper_shallow_list
+'
+
 test_done
-- 
tg: (52c9694..) t/revcache/graft (depends on: t/revcache/names)

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
  2009-10-19 20:31 ` Nick Edelen
@ 2009-10-21  9:15   ` Thomas Rast
  2009-10-21 13:44     ` Thomas Rast
  2009-10-27 21:11     ` Nick Edelen
  0 siblings, 2 replies; 8+ messages in thread
From: Thomas Rast @ 2009-10-21  9:15 UTC (permalink / raw)
  To: Nick Edelen
  Cc: Junio C Hamano, Nicolas Pitre, Johannes Schindelin, Sam Vilain,
	Michael J Gruber, Jeff King, Shawn O. Pearce, Andreas Ericsson,
	Christian Couder, git

Nick Edelen wrote:
> Adds support for graft commits in rev-cache (w/ test), and slightly alters
> graft mechanism.  Before, parse_commit() checked the graft list on every
> commit.  Now register_commit_graft() preemptively loads graft commits into
> memory, and sets a new 'graft' flag in the object.  This allows awareness of
> the commits' medical history without searching a (normally private) array upon
> each commit.

I felt adventurous and merged the topic into my local build, but I get
"error: duplicate graft data ..." in repositories with only a single
line in .git/info/grafts, which bisects to this commit (1c0a666 in
today's pu).

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism
  2009-10-21  9:15   ` Thomas Rast
@ 2009-10-21 13:44     ` Thomas Rast
  2009-10-27 21:11     ` Nick Edelen
  1 sibling, 0 replies; 8+ messages in thread
From: Thomas Rast @ 2009-10-21 13:44 UTC (permalink / raw)
  To: Nick Edelen
  Cc: Junio C Hamano, Nicolas Pitre, Johannes Schindelin, Sam Vilain,
	Michael J Gruber, Jeff King, Shawn O. Pearce, Andreas Ericsson,
	Christian Couder, git

Thomas Rast wrote:
> Nick Edelen wrote:
> > Adds support for graft commits in rev-cache (w/ test), and slightly alters
> > graft mechanism.  Before, parse_commit() checked the graft list on every
> > commit.  Now register_commit_graft() preemptively loads graft commits into
> > memory, and sets a new 'graft' flag in the object.  This allows awareness of
> > the commits' medical history without searching a (normally private) array upon
> > each commit.
> 
> I felt adventurous and merged the topic into my local build, but I get
> "error: duplicate graft data ..." in repositories with only a single
> line in .git/info/grafts, which bisects to this commit (1c0a666 in
> today's pu).

Here's the complaint in squashable form if you want to keep it as a
testcase:

diff --git i/t/t6001-rev-list-graft.sh w/t/t6001-rev-list-graft.sh
index b2131cd..49ba37b 100755
--- i/t/t6001-rev-list-graft.sh
+++ w/t/t6001-rev-list-graft.sh
@@ -110,4 +110,18 @@ do
 	"
 
 done
+
+duplicate_error="error: duplicate graft"
+
+test_expect_success 'duplicates: no false positives' '
+	echo $B0 $A2 > .git/info/grafts &&
+	! git rev-list -1 HEAD 2>&1 | grep -q "$duplicate_error"
+'
+
+test_expect_success 'duplicates: no false negatives' '
+	echo $B0 $A2 > .git/info/grafts &&
+	echo $B0 $A1 >> .git/info/grafts &&
+	git rev-list -1 HEAD 2>&1 | grep "$duplicate_error"
+'
+
 test_done


-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 7/6 (v4)] support for commit grafts, slight change to  general mechanism
  2009-10-21  9:15   ` Thomas Rast
  2009-10-21 13:44     ` Thomas Rast
@ 2009-10-27 21:11     ` Nick Edelen
  1 sibling, 0 replies; 8+ messages in thread
From: Nick Edelen @ 2009-10-27 21:11 UTC (permalink / raw)
  To: Thomas Rast
  Cc: Junio C Hamano, Nicolas Pitre, Johannes Schindelin, Sam Vilain,
	Michael J Gruber, Jeff King, Shawn O. Pearce, Andreas Ericsson,
	Christian Couder, git

> I felt adventurous and merged the topic into my local build, but I get
> "error: duplicate graft data ..." in repositories with only a single
> line in .git/info/grafts, which bisects to this commit (1c0a666 in
> today's pu).

Oops, it looks like there's a bug in my bugfix...  I had
parse_commit() accidentally calling itself through
register_commit_graft(); fixed now though.  Thanks for giving it a try
though!

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-10-27 21:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-07 14:11 [PATCH 7/6 (v4)] support for commit grafts, slight change to general mechanism Nick Edelen
2009-09-27 22:44 ` Nick Edelen
2009-09-29 16:34   ` Shawn O. Pearce
2009-09-30  8:00     ` Chris Johnsen
2009-10-19 20:31 ` Nick Edelen
2009-10-21  9:15   ` Thomas Rast
2009-10-21 13:44     ` Thomas Rast
2009-10-27 21:11     ` Nick Edelen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).