зеркало из https://github.com/microsoft/git.git
merge-ort: step 2 of tree writing -- function to create tree object
Create a new function, write_tree(), which will take a list of basenames, modes, and oids for a single directory and create a tree object in the object-store. We do not yet have just basenames, modes, and oids for just a single directory (we have a mixture of entries from all directory levels in the hierarchy) so we still die() before the current call to write_tree(), but the next patch will rectify that. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
a9945bba60
Коммит
ee4012dcf9
67
merge-ort.c
67
merge-ort.c
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "diff.h"
|
||||
#include "diffcore.h"
|
||||
#include "object-store.h"
|
||||
#include "strmap.h"
|
||||
#include "tree.h"
|
||||
#include "xdiff-interface.h"
|
||||
|
@ -523,6 +524,62 @@ struct directory_versions {
|
|||
struct string_list versions;
|
||||
};
|
||||
|
||||
static int tree_entry_order(const void *a_, const void *b_)
|
||||
{
|
||||
const struct string_list_item *a = a_;
|
||||
const struct string_list_item *b = b_;
|
||||
|
||||
const struct merged_info *ami = a->util;
|
||||
const struct merged_info *bmi = b->util;
|
||||
return base_name_compare(a->string, strlen(a->string), ami->result.mode,
|
||||
b->string, strlen(b->string), bmi->result.mode);
|
||||
}
|
||||
|
||||
static void write_tree(struct object_id *result_oid,
|
||||
struct string_list *versions,
|
||||
unsigned int offset,
|
||||
size_t hash_size)
|
||||
{
|
||||
size_t maxlen = 0, extra;
|
||||
unsigned int nr = versions->nr - offset;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct string_list relevant_entries = STRING_LIST_INIT_NODUP;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We want to sort the last (versions->nr-offset) entries in versions.
|
||||
* Do so by abusing the string_list API a bit: make another string_list
|
||||
* that contains just those entries and then sort them.
|
||||
*
|
||||
* We won't use relevant_entries again and will let it just pop off the
|
||||
* stack, so there won't be allocation worries or anything.
|
||||
*/
|
||||
relevant_entries.items = versions->items + offset;
|
||||
relevant_entries.nr = versions->nr - offset;
|
||||
QSORT(relevant_entries.items, relevant_entries.nr, tree_entry_order);
|
||||
|
||||
/* Pre-allocate some space in buf */
|
||||
extra = hash_size + 8; /* 8: 6 for mode, 1 for space, 1 for NUL char */
|
||||
for (i = 0; i < nr; i++) {
|
||||
maxlen += strlen(versions->items[offset+i].string) + extra;
|
||||
}
|
||||
strbuf_grow(&buf, maxlen);
|
||||
|
||||
/* Write each entry out to buf */
|
||||
for (i = 0; i < nr; i++) {
|
||||
struct merged_info *mi = versions->items[offset+i].util;
|
||||
struct version_info *ri = &mi->result;
|
||||
strbuf_addf(&buf, "%o %s%c",
|
||||
ri->mode,
|
||||
versions->items[offset+i].string, '\0');
|
||||
strbuf_add(&buf, ri->oid.hash, hash_size);
|
||||
}
|
||||
|
||||
/* Write this object file out, and record in result_oid */
|
||||
write_object_file(buf.buf, buf.len, tree_type, result_oid);
|
||||
strbuf_release(&buf);
|
||||
}
|
||||
|
||||
static void record_entry_for_tree(struct directory_versions *dir_metadata,
|
||||
const char *path,
|
||||
struct merged_info *mi)
|
||||
|
@ -675,9 +732,17 @@ static void process_entries(struct merge_options *opt,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: We can't actually write a tree yet, because dir_metadata just
|
||||
* contains all basenames of all files throughout the tree with their
|
||||
* mode and hash. Not only is that a nonsensical tree, it will have
|
||||
* lots of duplicates for paths such as "Makefile" or ".gitignore".
|
||||
*/
|
||||
die("Not yet implemented; need to process subtrees separately");
|
||||
write_tree(result_oid, &dir_metadata.versions, 0,
|
||||
opt->repo->hash_algo->rawsz);
|
||||
string_list_clear(&plist, 0);
|
||||
string_list_clear(&dir_metadata.versions, 0);
|
||||
die("Tree creation not yet implemented");
|
||||
}
|
||||
|
||||
void merge_switch_to_result(struct merge_options *opt,
|
||||
|
|
Загрузка…
Ссылка в новой задаче