Olivier Marin <dkr+ml.git@xxxxxxx> 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html