From: Johannes Schindelin <Johannes.Schindelin@xxxxxx> Instead of traversing them twice, we just build a list of branch switches, pick the one we're interested in, and free the list again. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- sha1_name.c | 61 ++++++++++++++++++++++++---------------------------------- 1 files changed, 25 insertions(+), 36 deletions(-) diff --git a/sha1_name.c b/sha1_name.c index 9e1538e..b21a1f0 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -5,6 +5,8 @@ #include "blob.h" #include "tree-walk.h" #include "refs.h" +#include "cache-tree.h" +#include "string-list.h" static int find_short_object_filename(int len, const char *name, unsigned char *sha1) { @@ -684,43 +686,31 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) return retval; } -struct grab_nth_branch_switch_cbdata { - int counting; - int nth; - struct strbuf *buf; -}; - -static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, +static int add_one_branch_switch(unsigned char *osha1, unsigned char *nsha1, const char *email, unsigned long timestamp, int tz, const char *message, void *cb_data) { - struct grab_nth_branch_switch_cbdata *cb = cb_data; + struct string_list *list = cb_data; const char *match = NULL, *target = NULL; size_t len; - if (!prefixcmp(message, "checkout: moving from ")) { - match = message + strlen("checkout: moving from "); - if ((target = strstr(match, " to ")) != NULL) - target += 4; - } - - if (!match) + if (prefixcmp(message, "checkout: moving from ")) return 0; - len = target - match - 4; - if (target[len] == '\n' && !strncmp(match, target, len)) - return 0; + match = message + strlen("checkout: moving from "); - if (cb->counting) { - cb->nth++; - return 0; + /* Is it "moving" from a branch to itself? Then ignore it. */ + if ((target = strstr(match, " to ")) != NULL) { + target += 4; + len = target - match - 4; + if (target[len] == '\n' && !strncmp(match, target, len)) + return 0; } + else + len = strchrnul(match, ' ') - match; + + string_list_append(xstrndup(match, len), list); - if (cb->nth-- <= 0) { - strbuf_reset(cb->buf); - strbuf_add(cb->buf, match, len); - return 1; - } return 0; } @@ -738,7 +728,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, int interpret_nth_last_branch(const char *name, struct strbuf *buf) { int nth; - struct grab_nth_branch_switch_cbdata cb; + struct string_list branch_list = { NULL, 0, 0, 0 }; const char *brace; char *num_end; @@ -751,18 +741,17 @@ int interpret_nth_last_branch(const char *name, struct strbuf *buf) if (num_end != brace) return -1; - cb.counting = 1; - cb.nth = 0; - cb.buf = buf; - for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb); + for_each_reflog_ent("HEAD", add_one_branch_switch, &branch_list); - if (cb.nth < nth) + if (branch_list.nr < nth) return 0; - cb.counting = 0; - cb.nth -= nth; - cb.buf = buf; - for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb); + strbuf_reset(buf); + strbuf_addstr(buf, branch_list.items[branch_list.nr - nth].string); + + /* force free()ing the items */ + branch_list.strdup_strings = 1; + string_list_clear(&branch_list, 0); return brace-name+1; } -- 1.6.1.315.g92577 -- 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