Merge branch 'jc/read-tree-safety' into next
authorJunio C Hamano <junkio@cox.net>
Wed, 17 May 2006 22:54:39 +0000 (15:54 -0700)
committerJunio C Hamano <junkio@cox.net>
Wed, 17 May 2006 22:54:39 +0000 (15:54 -0700)
* jc/read-tree-safety:
  read-tree -m -u: do not overwrite or remove untracked working tree files.

1  2 
read-tree.c

diff --cc 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);
                        *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;