Thread (9 messages) flat view 9 messages, 3 authors, 2016-06-15

Re: [PATCH] interpret_nth_last_branch(): avoid traversing the reflogs twice

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:45:59
Subsystem: the rest · Maintainer: Linus Torvalds

Possibly related (same subject, not in this thread)

Hi,

On Mon, 19 Jan 2009, Junio C Hamano wrote:
Junio C Hamano [off-list ref] writes:
quoted
Well, I would rather be in favor of something like this.

-- >8 --
Subject: interpret_nth_last_branch(): avoid traversing the reflog twice

You can have quite a many reflog entries, but you typically won't recall
which branch you were on after switching branches for more than several
times.

Instead of reading the reflog twice, this reads the branch switching event
and keeps the latest 16 (which is an arbitrary limitation that should be
plenty) such entry, to switch back to the branch we were recently on.

Signed-off-by: Junio C Hamano <redacted>
---
 sha1_name.c              |   48 +++++++++++++++++++++------------------------
 t/t2012-checkout-last.sh |   44 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 26 deletions(-)
diff --git a/sha1_name.c b/sha1_name.c
index 9e1538e..d6622f2 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -750,19 +746,19 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 	nth = strtol(name+3, &num_end, 10);
 	if (num_end != brace)
 		return -1;
...
-	if (cb.nth < nth)
-		return 0;
...
+	if (cb.cnt < nth)
+		return -1;
This should (obviously) be "return 0".
This, together with a removal of the hard-coded limit of 16 could be 
squashed with this patch:

-- snipsnap --
diff --git a/sha1_name.c b/sha1_name.c
index 2c5461e..9e5f444 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -691,11 +691,9 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1)
 	return retval;
 }
 
-#define MAX_PREVIOUS_BRANCH 16
-
 struct grab_nth_branch_switch_cbdata {
-	long cnt;
-	struct strbuf buf[MAX_PREVIOUS_BRANCH];
+	long cnt, alloc;
+	struct strbuf *buf;
 };
 
 static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
@@ -720,7 +718,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
 	if (target[len] == '\n' && !strncmp(match, target, len))
 		return 0;
 
-	nth = cb->cnt++ % MAX_PREVIOUS_BRANCH;
+	nth = cb->cnt++ % cb->alloc;
 	strbuf_reset(&cb->buf[nth]);
 	strbuf_add(&cb->buf[nth], match, len);
 	return 0;
@@ -753,19 +751,22 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf)
 	nth = strtol(name+3, &num_end, 10);
 	if (num_end != brace)
 		return -1;
-	if (nth <= 0 || MAX_PREVIOUS_BRANCH < nth)
+	if (nth <= 0)
 		return -1;
-	for (i = 0; i < MAX_PREVIOUS_BRANCH; i++)
+	cb.alloc = nth;
+	cb.buf = xmalloc(nth * sizeof(struct strbuf));
+	for (i = 0; i < nth; i++)
 		strbuf_init(&cb.buf[i], 20);
 	cb.cnt = 0;
 	for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb);
 	if (cb.cnt < nth)
-		return -1;
-	i = (cb.cnt + MAX_PREVIOUS_BRANCH - nth) % MAX_PREVIOUS_BRANCH;
+		return 0;
+	i = cb.cnt % nth;
 	strbuf_reset(buf);
 	strbuf_add(buf, cb.buf[i].buf, cb.buf[i].len);
-	for (i = 0; i < MAX_PREVIOUS_BRANCH; i++)
+	for (i = 0; i < nth; i++)
 		strbuf_release(&cb.buf[i]);
+	free(cb.buf);
 
 	return brace-name+1;
 }
-- 
1.6.1.347.g7b62749
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help