From: Junio C Hamano Date: Sun, 8 Apr 2007 06:52:40 +0000 (-0700) Subject: Merge branch 'jc/read-tree-df' (early part) X-Git-Tag: v1.5.2-rc0~73 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/640ee0d1cd771bf6093602f1beb143d356607446?ds=inline;hp=-c Merge branch 'jc/read-tree-df' (early part) * 'jc/read-tree-df' (early part): Fix switching to a branch with D/F when current branch has file D. Fix twoway_merge that passed d/f conflict marker to merged_entry(). Fix read-tree --prefix=dir/. unpack-trees: get rid of *indpos parameter. unpack_trees.c: pass unpack_trees_options structure to keep_entry() as well. add_cache_entry(): removal of file foo does not conflict with foo/bar --- 640ee0d1cd771bf6093602f1beb143d356607446 diff --combined builtin-read-tree.c index 213bd93c7f,5fb84b81a7..316fb0f8da --- a/builtin-read-tree.c +++ b/builtin-read-tree.c @@@ -84,7 -84,7 +84,7 @@@ static void prime_cache_tree(void } -static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [ []])"; +static const char read_tree_usage[] = "git-read-tree ( | [[-m [--aggressive] | --reset | --prefix=] [-u | -i]] [--exclude-per-directory=] [--index-output=] [ []])"; static struct lock_file lock_file; @@@ -100,7 -100,7 +100,7 @@@ int cmd_read_tree(int argc, const char setup_git_directory(); git_config(git_default_config); - newfd = hold_lock_file_for_update(&lock_file, get_index_file(), 1); + newfd = hold_locked_index(&lock_file, 1); git_config(git_default_config); @@@ -128,11 -128,6 +128,11 @@@ continue; } + if (!prefixcmp(arg, "--index-output=")) { + set_alternate_index_output(arg + 15); + continue; + } + /* "--prefix=/" means keep the current index * entries and put the entries from the tree under the * given subdirectory. @@@ -233,6 -228,7 +233,7 @@@ if (0 <= pos) die("file '%.*s' already exists.", pfxlen-1, opts.prefix); + opts.pos = -1 - pos; } if (opts.merge) { @@@ -272,7 -268,7 +273,7 @@@ } if (write_cache(newfd, active_cache, active_nr) || - close(newfd) || commit_lock_file(&lock_file)) + close(newfd) || commit_locked_index(&lock_file)) die("unable to write new index file"); return 0; } diff --combined read-cache.c index a8f8a6b2b2,823c2c3b08..54573ce2ee --- a/read-cache.c +++ b/read-cache.c @@@ -24,6 -24,8 +24,6 @@@ unsigned int active_nr, active_alloc, a struct cache_tree *active_cache_tree; -int cache_errno; - static void *cache_mmap; static size_t cache_mmap_size; @@@ -325,7 -327,7 +325,7 @@@ int remove_file_from_cache(const char * return 0; } -int add_file_to_index(const char *path, int verbose) +int add_file_to_cache(const char *path, int verbose) { int size, namelen; struct stat st; @@@ -485,6 -487,8 +485,8 @@@ static int has_file_name(const struct c continue; if (p->name[len] != '/') continue; + if (!ce_stage(p) && !p->ce_mode) + continue; retval = -1; if (!ok_to_replace) break; @@@ -517,26 -521,37 +519,37 @@@ static int has_dir_name(const struct ca pos = cache_name_pos(name, ntohs(create_ce_flags(len, stage))); if (pos >= 0) { - retval = -1; - if (!ok_to_replace) - break; - remove_cache_entry_at(pos); - continue; + /* + * Found one, but not so fast. This could + * be a marker that says "I was here, but + * I am being removed". Such an entry is + * not a part of the resulting tree, and + * it is Ok to have a directory at the same + * path. + */ + if (stage || active_cache[pos]->ce_mode) { + retval = -1; + if (!ok_to_replace) + break; + remove_cache_entry_at(pos); + continue; + } } + else + pos = -pos-1; /* * Trivial optimization: if we find an entry that * already matches the sub-directory, then we know * we're ok, and we can exit. */ - pos = -pos-1; while (pos < active_nr) { struct cache_entry *p = active_cache[pos]; if ((ce_namelen(p) <= len) || (p->name[len] != '/') || memcmp(p->name, name, len)) break; /* not our subdirectory */ - if (ce_stage(p) == stage) + if (ce_stage(p) == stage && (stage || p->ce_mode)) /* p is at the same stage as our entry, and * is a subdirectory of what we are looking * at, so we cannot have conflicts at our @@@ -560,12 -575,21 +573,21 @@@ */ static int check_file_directory_conflict(const struct cache_entry *ce, int pos, int ok_to_replace) { + int retval; + + /* + * When ce is an "I am going away" entry, we allow it to be added + */ + if (!ce_stage(ce) && !ce->ce_mode) + return 0; + /* * We check if the path is a sub-path of a subsequent pathname * first, since removing those will not change the position - * in the array + * in the array. */ - int retval = has_file_name(ce, pos, ok_to_replace); + retval = has_file_name(ce, pos, ok_to_replace); + /* * Then check if the path might have a clashing sub-directory * before it. @@@ -641,15 -665,14 +663,15 @@@ int add_cache_entry(struct cache_entry * For example, you'd want to do this after doing a "git-read-tree", * to link up the stat cache details with the proper files. */ -struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really) +static struct cache_entry *refresh_cache_ent(struct cache_entry *ce, int really, int *err) { struct stat st; struct cache_entry *updated; int changed, size; if (lstat(ce->name, &st) < 0) { - cache_errno = errno; + if (err) + *err = errno; return NULL; } @@@ -663,8 -686,7 +685,8 @@@ } if (ce_modified(ce, &st, really)) { - cache_errno = EINVAL; + if (err) + *err = EINVAL; return NULL; } @@@ -696,8 -718,6 +718,8 @@@ int refresh_cache(unsigned int flags for (i = 0; i < active_nr; i++) { struct cache_entry *ce, *new; + int cache_errno = 0; + ce = active_cache[i]; if (ce_stage(ce)) { while ((i < active_nr) && @@@ -711,7 -731,7 +733,7 @@@ continue; } - new = refresh_cache_entry(ce, really); + new = refresh_cache_ent(ce, really, &cache_errno); if (new == ce) continue; if (!new) { @@@ -739,11 -759,6 +761,11 @@@ return has_errors; } +struct cache_entry *refresh_cache_entry(struct cache_entry *ce, int really) +{ + return refresh_cache_ent(ce, really, NULL); +} + static int verify_hdr(struct cache_header *hdr, unsigned long size) { SHA_CTX c;