Subject: Re: [PATCH 0/3] Making remote tracking statistics available to other tools

From: Junio C Hamano <[email-masked]>
Date: Thu, 03 Jul 2008 12:07:12 -0700

Olivier Marin <[email-masked]> writes:

> Junio C Hamano a écrit :
>> The one I sent out was a bit hacky as the existing implementation inside
>> git-checkout was not designed to be cleanly reusable.
>> 
>> Here is a cleaned up series that could be applied.
>> 
>> [PATCH 1/3] Refactor "tracking statistics" code used by "git checkout"
>> [PATCH 2/3] git-status: show the remote tracking statistics
>> [PATCH 3/3] git-branch -v: show the remote tracking statistics
>
> Sorry, but the third patch does not work for me. FWIU, the problem comes from
> the revision walking code that is not reentrant because of the object cache.
> IOW, calling stats_tracking_info() more than once does not work: objects
> states changed after first call.
>
> I do not understand the code enough yet and I failed to fix it. The only way
> I found is by clearing obj_hash (object.c) but this seems the wrong thing to
> do.
>
> Ideas?

Thanks.

 remote.c                 |    4 +++
 revision.h               |    1 +
 t/t6040-tracking-info.sh |   52 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/remote.c b/remote.c
index bd5c3be..df8bd72 100644
--- a/remote.c
+++ b/remote.c
@@ -1295,6 +1295,10 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs)
 		else
 			(*num_theirs)++;
 	}
+
+	/* clear object flags smudged by the above traversal */
+	clear_commit_marks(ours, ALL_REV_FLAGS);
+	clear_commit_marks(theirs, ALL_REV_FLAGS);
 	return 1;
 }
 
diff --git a/revision.h b/revision.h
index abce500..e8bac6d 100644
--- a/revision.h
+++ b/revision.h
@@ -11,6 +11,7 @@
 #define ADDED		(1u<<7)	/* Parents already parsed and added? */
 #define SYMMETRIC_LEFT	(1u<<8)
 #define TOPOSORT	(1u<<9)	/* In the active toposort list.. */
+#define ALL_REV_FLAGS	((1u<<10)-1)
 
 struct rev_info;
 struct log_info;
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
new file mode 100755
index 0000000..960db2d
--- /dev/null
+++ b/t/t6040-tracking-info.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+test_description='remote tracking stats'
+
+. ./test-lib.sh
+
+advance () {
+	echo "$1" >"$1" &&
+	git add "$1" &&
+	test_tick &&
+	git commit -m "$1"
+}
+
+test_expect_success setup '
+	for i in a b c;
+	do
+		advance $i || break
+	done &&
+	git clone . test &&
+	(
+		cd test &&
+		git checkout -b b1 origin &&
+		git reset --hard HEAD^ &&
+		advance d &&
+		git checkout -b b2 origin &&
+		git reset --hard b1 &&
+		git checkout -b b3 origin &&
+		git reset --hard HEAD^ &&
+		git checkout -b b4 origin &&
+		advance e &&
+		advance f
+	)
+'
+
+script='s/^..\(b.\)[	 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p'
+cat >expect <<\EOF
+b1 ahead 1, behind 1
+b2 ahead 1, behind 1
+b3 behind 1
+b4 ahead 2
+EOF
+
+test_expect_success 'branch -v' '
+	(
+		cd test &&
+		git branch -v
+	) |
+	sed -n -e "$script" >actual &&
+	test_cmp expect actual
+'
+
+test_done