builtin-bundle.c - use stream buffered input for rev-list
[gitweb.git] / builtin-ls-files.c
index 4e1d5af634a1280288d7c8110571f1136343bf3e..d36181a75541df10c5dc1595ccca5a6fc429591f 100644 (file)
@@ -89,20 +89,38 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
 static void show_other_files(struct dir_struct *dir)
 {
        int i;
+
+
+       /*
+        * Skip matching and unmerged entries for the paths,
+        * since we want just "others".
+        *
+        * (Matching entries are normally pruned during
+        * the directory tree walk, but will show up for
+        * gitlinks because we don't necessarily have
+        * dir->show_other_directories set to suppress
+        * them).
+        */
        for (i = 0; i < dir->nr; i++) {
-               /* We should not have a matching entry, but we
-                * may have an unmerged entry for this path.
-                */
                struct dir_entry *ent = dir->entries[i];
-               int pos = cache_name_pos(ent->name, ent->len);
+               int len, pos;
                struct cache_entry *ce;
+
+               /*
+                * Remove the '/' at the end that directory
+                * walking adds for directory entries.
+                */
+               len = ent->len;
+               if (len && ent->name[len-1] == '/')
+                       len--;
+               pos = cache_name_pos(ent->name, len);
                if (0 <= pos)
-                       die("bug in show-other-files");
+                       continue;       /* exact match */
                pos = -pos - 1;
-               if (pos < active_nr) { 
+               if (pos < active_nr) {
                        ce = active_cache[pos];
-                       if (ce_namelen(ce) == ent->len &&
-                           !memcmp(ce->name, ent->name, ent->len))
+                       if (ce_namelen(ce) == len &&
+                           !memcmp(ce->name, ent->name, len))
                                continue; /* Yup, this one exists unmerged */
                }
                show_dir_entry(tag_other, ent);
@@ -216,7 +234,7 @@ static void show_files(struct dir_struct *dir, const char *prefix)
 
                if (baselen)
                        path = base = prefix;
-               read_directory(dir, path, base, baselen);
+               read_directory(dir, path, base, baselen, pathspec);
                if (show_others)
                        show_other_files(dir);
                if (show_killed)
@@ -451,9 +469,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
                break;
        }
 
-       if (require_work_tree &&
-                       (is_bare_repository() || is_inside_git_dir()))
-               die("This operation must be run in a work tree");
+       if (require_work_tree && !is_inside_work_tree()) {
+               const char *work_tree = get_git_work_tree();
+               if (!work_tree || chdir(work_tree))
+                       die("This operation must be run in a work tree");
+       }
 
        pathspec = get_pathspec(prefix, argv + i);