Merge branch 'jc/maint-reset-remove-unmerged-new'
authorJunio C Hamano <gitster@pobox.com>
Tue, 21 Oct 2008 20:48:41 +0000 (13:48 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Oct 2008 20:48:41 +0000 (13:48 -0700)
* jc/maint-reset-remove-unmerged-new:
  reset --hard/read-tree --reset -u: remove unmerged new paths

1  2 
read-cache.c

diff --cc read-cache.c
@@@ -1489,79 -1460,28 +1489,84 @@@ int write_index(const struct index_stat
  int read_index_unmerged(struct index_state *istate)
  {
        int i;
-       struct cache_entry **dst;
-       struct cache_entry *last = NULL;
+       int unmerged = 0;
  
        read_index(istate);
-       dst = istate->cache;
        for (i = 0; i < istate->cache_nr; i++) {
                struct cache_entry *ce = istate->cache[i];
-               if (ce_stage(ce)) {
-                       remove_name_hash(ce);
-                       if (last && !strcmp(ce->name, last->name))
-                               continue;
-                       cache_tree_invalidate_path(istate->cache_tree, ce->name);
-                       last = ce;
+               struct cache_entry *new_ce;
+               int size, len;
+               if (!ce_stage(ce))
                        continue;
-               }
-               *dst++ = ce;
+               unmerged = 1;
+               len = strlen(ce->name);
+               size = cache_entry_size(len);
+               new_ce = xcalloc(1, size);
+               hashcpy(new_ce->sha1, ce->sha1);
+               memcpy(new_ce->name, ce->name, len);
+               new_ce->ce_flags = create_ce_flags(len, 0);
+               new_ce->ce_mode = ce->ce_mode;
+               if (add_index_entry(istate, new_ce, 0))
+                       return error("%s: cannot drop to stage #0",
+                                    ce->name);
+               i = index_name_pos(istate, new_ce->name, len);
        }
-       istate->cache_nr = dst - istate->cache;
-       return !!last;
+       return unmerged;
  }
 +
 +struct update_callback_data
 +{
 +      int flags;
 +      int add_errors;
 +};
 +
 +static void update_callback(struct diff_queue_struct *q,
 +                          struct diff_options *opt, void *cbdata)
 +{
 +      int i;
 +      struct update_callback_data *data = cbdata;
 +
 +      for (i = 0; i < q->nr; i++) {
 +              struct diff_filepair *p = q->queue[i];
 +              const char *path = p->one->path;
 +              switch (p->status) {
 +              default:
 +                      die("unexpected diff status %c", p->status);
 +              case DIFF_STATUS_UNMERGED:
 +              case DIFF_STATUS_MODIFIED:
 +              case DIFF_STATUS_TYPE_CHANGED:
 +                      if (add_file_to_index(&the_index, path, data->flags)) {
 +                              if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
 +                                      die("updating files failed");
 +                              data->add_errors++;
 +                      }
 +                      break;
 +              case DIFF_STATUS_DELETED:
 +                      if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
 +                              break;
 +                      if (!(data->flags & ADD_CACHE_PRETEND))
 +                              remove_file_from_index(&the_index, path);
 +                      if (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))
 +                              printf("remove '%s'\n", path);
 +                      break;
 +              }
 +      }
 +}
 +
 +int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
 +{
 +      struct update_callback_data data;
 +      struct rev_info rev;
 +      init_revisions(&rev, prefix);
 +      setup_revisions(0, NULL, &rev, NULL);
 +      rev.prune_data = pathspec;
 +      rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
 +      rev.diffopt.format_callback = update_callback;
 +      data.flags = flags;
 +      data.add_errors = 0;
 +      rev.diffopt.format_callback_data = &data;
 +      run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
 +      return !!data.add_errors;
 +}
 +