Merge branch 'jk/maint-ls-files-other' into jk/fix-ls-files-other
authorJunio C Hamano <gitster@pobox.com>
Fri, 17 Oct 2008 20:03:52 +0000 (13:03 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 17 Oct 2008 20:03:52 +0000 (13:03 -0700)
* jk/maint-ls-files-other:
  refactor handling of "other" files in ls-files and status

Conflicts:
read-cache.c

1  2 
cache.h
read-cache.c
t/t7502-status.sh
wt-status.c

diff --cc cache.h
Simple merge
diff --cc read-cache.c
@@@ -1510,58 -1481,30 +1510,85 @@@ int read_index_unmerged(struct index_st
        return !!last;
  }
  
 +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;
 +}
 +
+ /*
+  * Returns 1 if the path is an "other" path with respect to
+  * the index; that is, the path is not mentioned in the index at all,
+  * either as a file, a directory with some files in the index,
+  * or as an unmerged entry.
+  *
+  * We helpfully remove a trailing "/" from directories so that
+  * the output of read_directory can be used as-is.
+  */
+ int index_name_is_other(const struct index_state *istate, const char *name,
+               int namelen)
+ {
+       int pos;
+       if (namelen && name[namelen - 1] == '/')
+               namelen--;
+       pos = index_name_pos(istate, name, namelen);
+       if (0 <= pos)
+               return 0;       /* exact match */
+       pos = -pos - 1;
+       if (pos < istate->cache_nr) {
+               struct cache_entry *ce = istate->cache[pos];
+               if (ce_namelen(ce) == namelen &&
+                   !memcmp(ce->name, name, namelen))
+                       return 0; /* Yup, this one exists unmerged */
+       }
+       return 1;
+ }
Simple merge
diff --cc wt-status.c
@@@ -277,23 -275,13 +277,12 @@@ static void wt_status_print_untracked(s
  
        read_directory(&dir, ".", "", 0, NULL);
        for(i = 0; i < dir.nr; i++) {
-               /* check for matching entry, which is unmerged; lifted from
-                * builtin-ls-files:show_other_files */
                struct dir_entry *ent = dir.entries[i];
-               int pos = cache_name_pos(ent->name, ent->len);
-               struct cache_entry *ce;
-               if (0 <= pos)
-                       die("bug in wt_status_print_untracked");
-               pos = -pos - 1;
-               if (pos < active_nr) {
-                       ce = active_cache[pos];
-                       if (ce_namelen(ce) == ent->len &&
-                           !memcmp(ce->name, ent->name, ent->len))
-                               continue;
-               }
+               if (!cache_name_is_other(ent->name, ent->len))
+                       continue;
                if (!shown_header) {
                        s->workdir_untracked = 1;
 -                      wt_status_print_header(s, "Untracked files",
 -                                             use_add_to_include_msg);
 +                      wt_status_print_untracked_header(s);
                        shown_header = 1;
                }
                color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t");