Skip to content

Commit

Permalink
rev-list --objects: use full pathname to help hashing.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Feb 24, 2006
1 parent eb38cc6 commit e646de0
Showing 1 changed file with 56 additions and 13 deletions.
69 changes: 56 additions & 13 deletions rev-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@ static int no_merges = 0;
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;
Expand Down Expand Up @@ -174,17 +204,23 @@ static int process_commit(struct commit * commit)
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;

Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -231,7 +274,7 @@ static void show_commit_list(struct commit_list *list)
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;
}
Expand All @@ -242,15 +285,15 @@ static void show_commit_list(struct commit_list *list)
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);
Expand Down Expand Up @@ -674,7 +717,7 @@ static struct commit_list *limit_list(struct commit_list *list)

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)
Expand Down

0 comments on commit e646de0

Please sign in to comment.