X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin-read-tree.c;h=49c10bf221961363b1edd073c926fe1bf92880c8;hb=82f930deadc9a7990cbc0988255e6a5afd641f4b;hp=d70411f2afc6f6efa3d3479b97f68c24db099051;hpb=62b693a0705c55dbc5573946f1f3fc6175cd2620;p=git.git diff --git a/builtin-read-tree.c b/builtin-read-tree.c index d70411f2a..49c10bf22 100644 --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@ -31,8 +31,7 @@ static int merge_size = 0; static struct object_list *trees = NULL; -static struct cache_entry df_conflict_entry = { -}; +static struct cache_entry df_conflict_entry; struct tree_entry_list { struct tree_entry_list *next; @@ -44,38 +43,30 @@ struct tree_entry_list { const unsigned char *sha1; }; -static struct tree_entry_list df_conflict_list = { - .name = NULL, - .next = &df_conflict_list -}; +static struct tree_entry_list df_conflict_list; typedef int (*merge_fn_t)(struct cache_entry **src); static struct tree_entry_list *create_tree_entry_list(struct tree *tree) { struct tree_desc desc; + struct name_entry one; struct tree_entry_list *ret = NULL; struct tree_entry_list **list_p = &ret; desc.buf = tree->buffer; desc.size = tree->size; - while (desc.size) { - unsigned mode; - const char *path; - const unsigned char *sha1; + while (tree_entry(&desc, &one)) { struct tree_entry_list *entry; - sha1 = tree_entry_extract(&desc, &path, &mode); - update_tree_entry(&desc); - entry = xmalloc(sizeof(struct tree_entry_list)); - entry->name = path; - entry->sha1 = sha1; - entry->mode = mode; - entry->directory = S_ISDIR(mode) != 0; - entry->executable = (mode & S_IXUSR) != 0; - entry->symlink = S_ISLNK(mode) != 0; + entry->name = one.path; + entry->sha1 = one.sha1; + entry->mode = one.mode; + entry->directory = S_ISDIR(one.mode) != 0; + entry->executable = (one.mode & S_IXUSR) != 0; + entry->symlink = S_ISLNK(one.mode) != 0; entry->next = NULL; *list_p = entry; @@ -339,14 +330,9 @@ static void setup_progress_signal(void) setitimer(ITIMER_REAL, &v, NULL); } +static struct checkout state; static void check_updates(struct cache_entry **src, int nr) { - static struct checkout state = { - .base_dir = "", - .force = 1, - .quiet = 1, - .refresh_cache = 1, - }; unsigned short mask = htons(CE_UPDATE); unsigned last_percent = 200, cnt = 0, total = 0; @@ -382,6 +368,7 @@ static void check_updates(struct cache_entry **src, int nr) fprintf(stderr, "%4u%% (%u/%u) done\r", percent, cnt, total); last_percent = percent; + progress_update = 0; } } } @@ -520,7 +507,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old) } merge->ce_flags &= ~htons(CE_STAGEMASK); - add_cache_entry(merge, ADD_CACHE_OK_TO_ADD); + add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); return 1; } @@ -531,7 +518,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old) else verify_absent(ce->name, "removed"); ce->ce_mode = 0; - add_cache_entry(ce, ADD_CACHE_OK_TO_ADD); + add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE); invalidate_ce_path(ce); return 1; } @@ -804,10 +791,8 @@ static int oneway_merge(struct cache_entry **src) return error("Cannot do a oneway merge of %d trees", merge_size); - if (!a) { - invalidate_ce_path(old); + if (!a) return deleted_entry(old, old); - } if (old && same(old, a)) { if (reset) { struct stat st; @@ -822,51 +807,47 @@ static int oneway_merge(struct cache_entry **src) static int read_cache_unmerged(void) { - int i, deleted; + int i; struct cache_entry **dst; + struct cache_entry *last = NULL; read_cache(); dst = active_cache; - deleted = 0; for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; if (ce_stage(ce)) { - deleted++; + if (last && !strcmp(ce->name, last->name)) + continue; invalidate_ce_path(ce); - continue; + last = ce; + ce->ce_mode = 0; + ce->ce_flags &= ~htons(CE_STAGEMASK); } - if (deleted) - *dst = ce; - dst++; + *dst++ = ce; } - active_nr -= deleted; - return deleted; + active_nr = dst - active_cache; + return !!last; } static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) { struct tree_desc desc; + struct name_entry entry; int cnt; memcpy(it->sha1, tree->object.sha1, 20); desc.buf = tree->buffer; desc.size = tree->size; cnt = 0; - while (desc.size) { - unsigned mode; - const char *name; - const unsigned char *sha1; - - sha1 = tree_entry_extract(&desc, &name, &mode); - update_tree_entry(&desc); - if (!S_ISDIR(mode)) + while (tree_entry(&desc, &entry)) { + if (!S_ISDIR(entry.mode)) cnt++; else { struct cache_tree_sub *sub; - struct tree *subtree = lookup_tree(sha1); + struct tree *subtree = lookup_tree(entry.sha1); if (!subtree->object.parsed) parse_tree(subtree); - sub = cache_tree_sub(it, name); + sub = cache_tree_sub(it, entry.path); sub->cache_tree = cache_tree(); prime_cache_tree_rec(sub->cache_tree, subtree); cnt += sub->cache_tree->entry_count; @@ -887,20 +868,25 @@ static void prime_cache_tree(void) static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [ []])"; -static struct cache_file cache_file; +static struct lock_file lock_file; -int cmd_read_tree(int argc, const char **argv, char **envp) +int cmd_read_tree(int argc, const char **argv, const char *prefix) { int i, newfd, stage = 0; unsigned char sha1[20]; merge_fn_t fn = NULL; - setup_git_directory(); + df_conflict_list.next = &df_conflict_list; + state.base_dir = ""; + state.force = 1; + state.quiet = 1; + state.refresh_cache = 1; + git_config(git_default_config); - newfd = hold_index_file_for_update(&cache_file, get_index_file()); + newfd = hold_lock_file_for_update(&lock_file, get_index_file()); if (newfd < 0) - die("unable to create new cachefile"); + die("unable to create new index file"); git_config(git_default_config); @@ -945,7 +931,10 @@ int cmd_read_tree(int argc, const char **argv, char **envp) continue; } - /* This differs from "-m" in that we'll silently ignore unmerged entries */ + /* This differs from "-m" in that we'll silently ignore + * unmerged entries and overwrite working tree files that + * correspond to them. + */ if (!strcmp(arg, "--reset")) { if (stage || merge || prefix) usage(read_tree_usage); @@ -1040,13 +1029,13 @@ int cmd_read_tree(int argc, const char **argv, char **envp) * valid cache-tree because the index must match exactly * what came from the tree. */ - if (trees && trees->item && (!merge || (stage == 2))) { + if (trees && trees->item && !prefix && (!merge || (stage == 2))) { cache_tree_free(&active_cache_tree); prime_cache_tree(); } if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) + close(newfd) || commit_lock_file(&lock_file)) die("unable to write new index file"); return 0; }