summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: eb38cc6)
raw | patch | inline | side by side (parent: eb38cc6)
author | Junio C Hamano <junkio@cox.net> | |
Thu, 23 Feb 2006 06:10:24 +0000 (22:10 -0800) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Fri, 24 Feb 2006 07:44:42 +0000 (23:44 -0800) |
This helps to group the same files from different revs together,
while spreading files with the same basename in different
directories, to help pack-object.
Signed-off-by: Junio C Hamano <junkio@cox.net>
while spreading files with the same basename in different
directories, to help pack-object.
Signed-off-by: Junio C Hamano <junkio@cox.net>
rev-list.c | patch | blob | history |
diff --git a/rev-list.c b/rev-list.c
index b5de0759f9b1f41899b90807c44ee242d478a20e..dda6fcaa9694c332432da03e5b1ec0d0b46f0f0b 100644 (file)
--- a/rev-list.c
+++ b/rev-list.c
static const char **paths = NULL;
static int remove_empty_trees = 0;
+struct name_path {
+ struct name_path *up;
+ int elem_len;
+ const char *elem;
+};
+
+static char *path_name(struct name_path *path, const char *name)
+{
+ struct name_path *p;
+ char *n, *m;
+ int nlen = strlen(name);
+ int len = nlen + 1;
+
+ for (p = path; p; p = p->up) {
+ if (p->elem_len)
+ len += p->elem_len + 1;
+ }
+ n = xmalloc(len);
+ m = n + len - (nlen + 1);
+ strcpy(m, name);
+ for (p = path; p; p = p->up) {
+ if (p->elem_len) {
+ m -= p->elem_len + 1;
+ memcpy(m, p->elem, p->elem_len);
+ m[p->elem_len] = '/';
+ }
+ }
+ return n;
+}
+
static void show_commit(struct commit *commit)
{
commit->object.flags |= SHOWN;
return CONTINUE;
}
-static struct object_list **add_object(struct object *obj, struct object_list **p, const char *name)
+static struct object_list **add_object(struct object *obj,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name)
{
struct object_list *entry = xmalloc(sizeof(*entry));
entry->item = obj;
entry->next = *p;
- entry->name = name;
+ entry->name = path_name(path, name);
*p = entry;
return &entry->next;
}
-static struct object_list **process_blob(struct blob *blob, struct object_list **p, const char *name)
+static struct object_list **process_blob(struct blob *blob,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name)
{
struct object *obj = &blob->object;
@@ -193,13 +229,17 @@ static struct object_list **process_blob(struct blob *blob, struct object_list *
if (obj->flags & (UNINTERESTING | SEEN))
return p;
obj->flags |= SEEN;
- return add_object(obj, p, name);
+ return add_object(obj, p, path, name);
}
-static struct object_list **process_tree(struct tree *tree, struct object_list **p, const char *name)
+static struct object_list **process_tree(struct tree *tree,
+ struct object_list **p,
+ struct name_path *path,
+ const char *name)
{
struct object *obj = &tree->object;
struct tree_entry_list *entry;
+ struct name_path me;
if (!tree_objects)
return p;
@@ -208,15 +248,18 @@ static struct object_list **process_tree(struct tree *tree, struct object_list *
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
- p = add_object(obj, p, name);
+ p = add_object(obj, p, path, name);
+ me.up = path;
+ me.elem = name;
+ me.elem_len = strlen(name);
entry = tree->entries;
tree->entries = NULL;
while (entry) {
struct tree_entry_list *next = entry->next;
if (entry->directory)
- p = process_tree(entry->item.tree, p, entry->name);
+ p = process_tree(entry->item.tree, p, &me, entry->name);
else
- p = process_blob(entry->item.blob, p, entry->name);
+ p = process_blob(entry->item.blob, p, &me, entry->name);
free(entry);
entry = next;
}
while (list) {
struct commit *commit = pop_most_recent_commit(&list, SEEN);
- p = process_tree(commit->tree, p, "");
+ p = process_tree(commit->tree, p, NULL, "");
if (process_commit(commit) == STOP)
break;
}
continue;
if (obj->type == tag_type) {
obj->flags |= SEEN;
- p = add_object(obj, p, name);
+ p = add_object(obj, p, NULL, name);
continue;
}
if (obj->type == tree_type) {
- p = process_tree((struct tree *)obj, p, name);
+ p = process_tree((struct tree *)obj, p, NULL, name);
continue;
}
if (obj->type == blob_type) {
- p = process_blob((struct blob *)obj, p, name);
+ p = process_blob((struct blob *)obj, p, NULL, name);
continue;
}
die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
static void add_pending_object(struct object *obj, const char *name)
{
- add_object(obj, &pending_objects, name);
+ add_object(obj, &pending_objects, NULL, name);
}
static struct commit *get_commit_reference(const char *name, const unsigned char *sha1, unsigned int flags)