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);
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)
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);
*/
int num, errors = 0;
for (num = 0; pathspec[num]; num++) {
+ int other, found_dup;
+
if (ps_matched[num])
continue;
+ /*
+ * The caller might have fed identical pathspec
+ * twice. Do not barf on such a mistake.
+ */
+ for (found_dup = other = 0;
+ !found_dup && pathspec[other];
+ other++) {
+ if (other == num || !ps_matched[other])
+ continue;
+ if (!strcmp(pathspec[other], pathspec[num]))
+ /*
+ * Ok, we have a match already.
+ */
+ found_dup = 1;
+ }
+ if (found_dup)
+ continue;
+
error("pathspec '%s' did not match any file(s) known to git.",
pathspec[num] + prefix_offset);
errors++;