summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/technical/api-tree-walking.txt4
-rw-r--r--builtin/merge-tree.c5
-rw-r--r--tree-walk.c21
-rw-r--r--tree-walk.h3
-rw-r--r--unpack-trees.c16
5 files changed, 32 insertions, 17 deletions
diff --git a/Documentation/technical/api-tree-walking.txt b/Documentation/technical/api-tree-walking.txt
index 59d78e0362..7962e32854 100644
--- a/Documentation/technical/api-tree-walking.txt
+++ b/Documentation/technical/api-tree-walking.txt
@@ -138,6 +138,10 @@ same in the next callback invocation.
This utilizes the memory structure of a tree entry to avoid the
overhead of using a generic strlen().
+`strbuf_make_traverse_path`::
+
+ Convenience wrapper to `make_traverse_path` into a strbuf.
+
Authors
-------
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 0629c87b19..87d949cf88 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -180,8 +180,9 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const stru
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
{
- char *path = xmallocz(traverse_path_len(info, tree_entry_len(n)));
- return make_traverse_path(path, info, n->path, n->pathlen);
+ struct strbuf buf = STRBUF_INIT;
+ strbuf_make_traverse_path(&buf, info, n->path, n->pathlen);
+ return strbuf_detach(&buf, NULL);
}
static void resolve(const struct traverse_info *info, struct name_entry *ours, struct name_entry *result)
diff --git a/tree-walk.c b/tree-walk.c
index 70f9eb5f1b..c2952f3793 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -200,6 +200,17 @@ char *make_traverse_path(char *path, const struct traverse_info *info,
return path;
}
+void strbuf_make_traverse_path(struct strbuf *out,
+ const struct traverse_info *info,
+ const char *name, size_t namelen)
+{
+ size_t len = traverse_path_len(info, namelen);
+
+ strbuf_grow(out, len);
+ make_traverse_path(out->buf + out->len, info, name, namelen);
+ strbuf_setlen(out, out->len + len);
+}
+
struct tree_desc_skip {
struct tree_desc_skip *prev;
const void *ptr;
@@ -396,12 +407,10 @@ int traverse_trees(struct index_state *istate,
tx[i].d = t[i];
if (info->prev) {
- strbuf_grow(&base, info->pathlen);
- make_traverse_path(base.buf, info->prev, info->name,
- info->namelen);
- base.buf[info->pathlen-1] = '/';
- strbuf_setlen(&base, info->pathlen);
- traverse_path = xstrndup(base.buf, info->pathlen);
+ strbuf_make_traverse_path(&base, info->prev,
+ info->name, info->namelen);
+ strbuf_addch(&base, '/');
+ traverse_path = xstrndup(base.buf, base.len);
} else {
traverse_path = xstrndup(info->name, info->pathlen);
}
diff --git a/tree-walk.h b/tree-walk.h
index a25c751c1e..994c14a499 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -72,6 +72,9 @@ struct traverse_info {
int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned short *);
char *make_traverse_path(char *path, const struct traverse_info *info,
const char *name, size_t namelen);
+void strbuf_make_traverse_path(struct strbuf *out,
+ const struct traverse_info *info,
+ const char *name, size_t namelen);
void setup_traverse_info(struct traverse_info *info, const char *base);
static inline size_t traverse_path_len(const struct traverse_info *info,
diff --git a/unpack-trees.c b/unpack-trees.c
index 492eff666a..c3059c2440 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -686,21 +686,19 @@ static int index_pos_by_traverse_info(struct name_entry *names,
struct traverse_info *info)
{
struct unpack_trees_options *o = info->data;
- size_t len = traverse_path_len(info, tree_entry_len(names));
- char *name = xmalloc(len + 1 /* slash */ + 1 /* NUL */);
+ struct strbuf name = STRBUF_INIT;
int pos;
- make_traverse_path(name, info, names->path, names->pathlen);
- name[len++] = '/';
- name[len] = '\0';
- pos = index_name_pos(o->src_index, name, len);
+ strbuf_make_traverse_path(&name, info, names->path, names->pathlen);
+ strbuf_addch(&name, '/');
+ pos = index_name_pos(o->src_index, name.buf, name.len);
if (pos >= 0)
BUG("This is a directory and should not exist in index");
pos = -pos - 1;
- if (!starts_with(o->src_index->cache[pos]->name, name) ||
- (pos > 0 && starts_with(o->src_index->cache[pos-1]->name, name)))
+ if (!starts_with(o->src_index->cache[pos]->name, name.buf) ||
+ (pos > 0 && starts_with(o->src_index->cache[pos-1]->name, name.buf)))
BUG("pos must point at the first entry in this directory");
- free(name);
+ strbuf_release(&name);
return pos;
}