Signed-off-by: Chuck Lever <cel@netapp.com> --- write-tree.c | 110 ++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 69 insertions(+), 41 deletions(-) diff --git a/write-tree.c b/write-tree.c --- a/write-tree.c +++ b/write-tree.c @@ -5,7 +5,7 @@ */ #include "cache.h" -static int missing_ok = 0; +static int funny, missing_ok = 0; static int check_valid_sha1(unsigned char *sha1) { @@ -18,8 +18,9 @@ static int check_valid_sha1(unsigned cha return ret ? 0 : -1; } -static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1) +static int write_tree(struct cache_cursor *cc, int maxentries, const char *base, int baselen, unsigned char *returnsha1) { + struct cache_cursor next = *cc; unsigned char subdir_sha1[20]; unsigned long size, offset; char *buffer; @@ -32,7 +33,7 @@ static int write_tree(struct cache_entry nr = 0; while (nr < maxentries) { - struct cache_entry *ce = cachep[nr]; + struct cache_entry *ce = cc_to_ce(&next); const char *pathname = ce->name, *filename, *dirname; int pathlen = ce_namelen(ce), entrylen; unsigned char *sha1; @@ -51,15 +52,20 @@ static int write_tree(struct cache_entry if (dirname) { int subdir_written; - subdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1); - nr += subdir_written; - + subdir_written = write_tree(&next, + maxentries - nr, + pathname, + dirname - pathname + 1, + subdir_sha1); + /* Now we need to write out the directory entry into this tree.. */ mode = S_IFDIR; pathlen = dirname - pathname; /* ..but the directory entry doesn't count towards the total count */ - nr--; + nr += subdir_written - 1; + while (--subdir_written) + next_cc(&next); sha1 = subdir_sha1; } @@ -76,6 +82,7 @@ static int write_tree(struct cache_entry memcpy(buffer + offset, sha1, 20); offset += 20; nr++; + next_cc(&next); } write_sha1_file(buffer, offset, "tree", returnsha1); @@ -83,11 +90,57 @@ static int write_tree(struct cache_entry return nr; } +static int verify_merged(struct cache_cursor *cc, struct cache_entry *ce) +{ + if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) { + if (10 < ++funny) { + fprintf(stderr, "...\n"); + return -1; + } + fprintf(stderr, "%s: unmerged (%s)\n", ce->name, sha1_to_hex(ce->sha1)); + } + + next_cc(cc); + return 0; +} + +/* + * path/file always comes after path because of the way + * the cache is sorted. Also path can appear only once, + * which means conflicting one would immediately follow. + */ +static int verify_path(struct cache_cursor *cc, struct cache_entry *ce) +{ + struct cache_entry *next; + const char *next_name, *this_name = ce->name; + int this_len = strlen(this_name); + + /* don't check the last cache entry */ + next_cc(cc); + if (cache_eof(cc)) + return -1; + next = cc_to_ce(cc); + next_name = next->name; + + if (this_len < strlen(next_name) && + strncmp(this_name, next_name, this_len) == 0 && + next_name[this_len] == '/') { + if (10 < ++funny) { + fprintf(stderr, "...\n"); + return -1; + } + fprintf(stderr, "You have both %s and %s\n", + this_name, next_name); + } + + return 0; +} + int main(int argc, char **argv) { - int i, funny; - int entries = read_cache(); + struct cache_cursor cc; unsigned char sha1[20]; + int entries; if (argc == 2) { if (!strcmp(argv[1], "--missing-ok")) @@ -99,53 +152,28 @@ int main(int argc, char **argv) if (argc > 2) die("too many options"); + entries = read_cache(); if (entries < 0) die("git-write-tree: error reading cache"); /* Verify that the tree is merged */ funny = 0; - for (i = 0; i < entries; i++) { - struct cache_entry *ce = active_cache[i]; - if (ntohs(ce->ce_flags) & ~CE_NAMEMASK) { - if (10 < ++funny) { - fprintf(stderr, "...\n"); - break; - } - fprintf(stderr, "%s: unmerged (%s)\n", ce->name, sha1_to_hex(ce->sha1)); - } - } + walk_cache(verify_merged); if (funny) - die("git-write-tree: not able to write tree"); + die("git-write-tree: verify_merged: not able to write tree"); /* Also verify that the cache does not have path and path/file * at the same time. At this point we know the cache has only * stage 0 entries. */ funny = 0; - for (i = 0; i < entries - 1; i++) { - /* path/file always comes after path because of the way - * the cache is sorted. Also path can appear only once, - * which means conflicting one would immediately follow. - */ - const char *this_name = active_cache[i]->name; - const char *next_name = active_cache[i+1]->name; - int this_len = strlen(this_name); - if (this_len < strlen(next_name) && - strncmp(this_name, next_name, this_len) == 0 && - next_name[this_len] == '/') { - if (10 < ++funny) { - fprintf(stderr, "...\n"); - break; - } - fprintf(stderr, "You have both %s and %s\n", - this_name, next_name); - } - } + walk_cache(verify_path); if (funny) - die("git-write-tree: not able to write tree"); + die("git-write-tree: verify_path: not able to write tree"); /* Ok, write it out */ - if (write_tree(active_cache, entries, "", 0, sha1) != entries) + init_cc(&cc); + if (write_tree(&cc, entries, "", 0, sha1) != entries) die("git-write-tree: internal error"); printf("%s\n", sha1_to_hex(sha1)); return 0; - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.htmlReceived on Tue Sep 13 00:59:09 2005
This archive was generated by hypermail 2.1.8 : 2005-09-13 00:59:15 EST