From: Junio C Hamano Date: Wed, 17 May 2006 22:54:39 +0000 (-0700) Subject: Merge branch 'jc/read-tree-safety' into next X-Git-Tag: v1.4.1-rc1~91 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=22b49b7fb960921146ebc7b49fe1f014e828b671;p=git.git Merge branch 'jc/read-tree-safety' into next * jc/read-tree-safety: read-tree -m -u: do not overwrite or remove untracked working tree files. --- 22b49b7fb960921146ebc7b49fe1f014e828b671 diff --cc read-tree.c index 675a59f80,82e2a9a4d..a3ada55c1 --- a/read-tree.c +++ b/read-tree.c @@@ -429,12 -426,21 +429,27 @@@ static void verify_uptodate(struct cach die("Entry '%s' not uptodate. Cannot merge.", ce->name); } +static void invalidate_ce_path(struct cache_entry *ce) +{ + if (ce) + cache_tree_invalidate_path(active_cache_tree, ce->name); +} + + /* + * We do not want to remove or overwrite a working tree file that + * is not tracked. + */ + static void verify_absent(const char *path, const char *action) + { + struct stat st; + + if (index_only || reset || !update) + return; + if (!lstat(path, &st)) + die("Untracked working tree file '%s' " + "would be %s by merge.", path, action); + } + static int merged_entry(struct cache_entry *merge, struct cache_entry *old) { merge->ce_flags |= htons(CE_UPDATE); @@@ -450,11 -456,11 +465,14 @@@ *merge = *old; } else { verify_uptodate(old); + invalidate_ce_path(old); } } -- else ++ else { + verify_absent(merge->name, "overwritten"); + invalidate_ce_path(merge); ++ } + merge->ce_flags &= ~htons(CE_STAGEMASK); add_cache_entry(merge, ADD_CACHE_OK_TO_ADD); return 1; @@@ -464,9 -470,10 +482,11 @@@ static int deleted_entry(struct cache_e { if (old) verify_uptodate(old); + else + verify_absent(ce->name, "removed"); ce->ce_mode = 0; add_cache_entry(ce, ADD_CACHE_OK_TO_ADD); + invalidate_ce_path(ce); return 1; } @@@ -723,10 -723,8 +758,10 @@@ static int oneway_merge(struct cache_en return error("Cannot do a oneway merge of %d trees", merge_size); - if (!a) + if (!a) { + invalidate_ce_path(old); - return deleted_entry(old, NULL); + return deleted_entry(old, old); + } if (old && same(old, a)) { if (reset) { struct stat st;