Merge branch 'ab/fetch-tags-noclobber'
[gitweb.git] / merge-recursive.c
index 07d792fd10c6bcee9ca12367fc2ad708fb26f9c4..bd053c70dfc518b6265ec273aad2e61c05d60d18 100644 (file)
@@ -3070,10 +3070,26 @@ static int merge_content(struct merge_options *o,
        if (mfi.clean &&
            was_tracked_and_matches(o, path, &mfi.oid, mfi.mode) &&
            !df_conflict_remains) {
+               int pos;
+               struct cache_entry *ce;
+
                output(o, 3, _("Skipped %s (merged same as existing)"), path);
                if (add_cacheinfo(o, mfi.mode, &mfi.oid, path,
                                  0, (!o->call_depth && !is_dirty), 0))
                        return -1;
+               /*
+                * However, add_cacheinfo() will delete the old cache entry
+                * and add a new one.  We need to copy over any skip_worktree
+                * flag to avoid making the file appear as if it were
+                * deleted by the user.
+                */
+               pos = index_name_pos(&o->orig_index, path, strlen(path));
+               ce = o->orig_index.cache[pos];
+               if (ce_skip_worktree(ce)) {
+                       pos = index_name_pos(&the_index, path, strlen(path));
+                       ce = the_index.cache[pos];
+                       ce->ce_flags |= CE_SKIP_WORKTREE;
+               }
                return mfi.clean;
        }
 
@@ -3281,6 +3297,13 @@ int merge_trees(struct merge_options *o,
                struct tree **result)
 {
        int code, clean;
+       struct strbuf sb = STRBUF_INIT;
+
+       if (!o->call_depth && index_has_changes(&the_index, head, &sb)) {
+               err(o, _("Your local changes to the following files would be overwritten by merge:\n  %s"),
+                   sb.buf);
+               return -1;
+       }
 
        if (o->subtree_shift) {
                merge = shift_tree_object(head, merge, o->subtree_shift);
@@ -3288,13 +3311,6 @@ int merge_trees(struct merge_options *o,
        }
 
        if (oid_eq(&common->object.oid, &merge->object.oid)) {
-               struct strbuf sb = STRBUF_INIT;
-
-               if (!o->call_depth && index_has_changes(&sb)) {
-                       err(o, _("Dirty index: cannot merge (dirty: %s)"),
-                           sb.buf);
-                       return 0;
-               }
                output(o, 0, _("Already up to date!"));
                *result = head;
                return 1;