示例#1
0
文件: commit.c 项目: moy/git
/*
 * Take a union of paths in the index and the named tree (typically, "HEAD"),
 * and return the paths that match the given pattern in list.
 */
static int list_paths(struct string_list *list, const char *with_tree,
		      const char *prefix, const char **pattern)
{
	int i;
	char *m;

	for (i = 0; pattern[i]; i++)
		;
	m = xcalloc(1, i);

	if (with_tree) {
		const char *max_prefix = pathspec_prefix(prefix, pattern);
		overlay_tree_on_cache(with_tree, max_prefix);
	}

	for (i = 0; i < active_nr; i++) {
		struct cache_entry *ce = active_cache[i];
		struct string_list_item *item;

		if (ce->ce_flags & CE_UPDATE)
			continue;
		if (!match_pathspec(pattern, ce->name, ce_namelen(ce), 0, m))
			continue;
		item = string_list_insert(list, ce->name);
		if (ce_skip_worktree(ce))
			item->util = item; /* better a valid pointer than a fake one */
	}

	return report_path_error(m, pattern, prefix);
}
示例#2
0
文件: ls-files.c 项目: skshiro/git
int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
{
    int require_work_tree = 0, show_tag = 0;
    const char *max_prefix;
    struct dir_struct dir;
    struct option builtin_ls_files_options[] = {
        {   OPTION_CALLBACK, 'z', NULL, NULL, NULL,
            "paths are separated with NUL character",
            PARSE_OPT_NOARG, option_parse_z
        },
        OPT_BOOLEAN('t', NULL, &show_tag,
        "identify the file status with tags"),
        OPT_BOOLEAN('v', NULL, &show_valid_bit,
        "use lowercase letters for 'assume unchanged' files"),
        OPT_BOOLEAN('c', "cached", &show_cached,
        "show cached files in the output (default)"),
        OPT_BOOLEAN('d', "deleted", &show_deleted,
        "show deleted files in the output"),
        OPT_BOOLEAN('m', "modified", &show_modified,
        "show modified files in the output"),
        OPT_BOOLEAN('o', "others", &show_others,
        "show other files in the output"),
        OPT_BIT('i', "ignored", &dir.flags,
        "show ignored files in the output",
        DIR_SHOW_IGNORED),
        OPT_BOOLEAN('s', "stage", &show_stage,
        "show staged contents' object name in the output"),
        OPT_BOOLEAN('k', "killed", &show_killed,
        "show files on the filesystem that need to be removed"),
        OPT_BIT(0, "directory", &dir.flags,
        "show 'other' directories' name only",
        DIR_SHOW_OTHER_DIRECTORIES),
        OPT_NEGBIT(0, "empty-directory", &dir.flags,
        "don't show empty directories",
        DIR_HIDE_EMPTY_DIRECTORIES),
        OPT_BOOLEAN('u', "unmerged", &show_unmerged,
        "show unmerged files in the output"),
        OPT_BOOLEAN(0, "resolve-undo", &show_resolve_undo,
        "show resolve-undo information"),
        {   OPTION_CALLBACK, 'x', "exclude", &dir.exclude_list[EXC_CMDL], "pattern",
            "skip files matching pattern",
            0, option_parse_exclude
        },
        {   OPTION_CALLBACK, 'X', "exclude-from", &dir, "file",
            "exclude patterns are read from <file>",
            0, option_parse_exclude_from
        },
        OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, "file",
        "read additional per-directory exclude patterns in <file>"),
        {   OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
            "add the standard git exclusions",
            PARSE_OPT_NOARG, option_parse_exclude_standard
        },
        {   OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
            "make the output relative to the project top directory",
            PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL
        },
        OPT_BOOLEAN(0, "error-unmatch", &error_unmatch,
        "if any <file> is not in the index, treat this as an error"),
        OPT_STRING(0, "with-tree", &with_tree, "tree-ish",
        "pretend that paths removed since <tree-ish> are still present"),
        OPT__ABBREV(&abbrev),
        OPT_END()
    };

    memset(&dir, 0, sizeof(dir));
    prefix = cmd_prefix;
    if (prefix)
        prefix_len = strlen(prefix);
    git_config(git_default_config, NULL);

    if (read_cache() < 0)
        die("index file corrupt");

    argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
                         ls_files_usage, 0);
    if (show_tag || show_valid_bit) {
        tag_cached = "H ";
        tag_unmerged = "M ";
        tag_removed = "R ";
        tag_modified = "C ";
        tag_other = "? ";
        tag_killed = "K ";
        tag_skip_worktree = "S ";
        tag_resolve_undo = "U ";
    }
    if (show_modified || show_others || show_deleted || (dir.flags & DIR_SHOW_IGNORED) || show_killed)
        require_work_tree = 1;
    if (show_unmerged)
        /*
         * There's no point in showing unmerged unless
         * you also show the stage information.
         */
        show_stage = 1;
    if (dir.exclude_per_dir)
        exc_given = 1;

    if (require_work_tree && !is_inside_work_tree())
        setup_work_tree();

    pathspec = get_pathspec(prefix, argv);

    /* be nice with submodule paths ending in a slash */
    if (pathspec)
        strip_trailing_slash_from_submodules();

    /* Find common prefix for all pathspec's */
    max_prefix = pathspec_prefix(prefix);

    /* Treat unmatching pathspec elements as errors */
    if (pathspec && error_unmatch) {
        int num;
        for (num = 0; pathspec[num]; num++)
            ;
        ps_matched = xcalloc(1, num);
    }

    if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
        die("ls-files --ignored needs some exclude pattern");

    /* With no flags, we default to showing the cached files */
    if (!(show_stage | show_deleted | show_others | show_unmerged |
            show_killed | show_modified | show_resolve_undo))
        show_cached = 1;

    if (max_prefix)
        prune_cache(max_prefix);
    if (with_tree) {
        /*
         * Basic sanity check; show-stages and show-unmerged
         * would not make any sense with this option.
         */
        if (show_stage || show_unmerged)
            die("ls-files --with-tree is incompatible with -s or -u");
        overlay_tree_on_cache(with_tree, max_prefix);
    }
    show_files(&dir);
    if (show_resolve_undo)
        show_ru_info();

    if (ps_matched) {
        int bad;
        bad = report_path_error(ps_matched, pathspec, prefix_len);
        if (bad)
            fprintf(stderr, "Did you forget to 'git add'?\n");

        return bad ? 1 : 0;
    }

    return 0;
}