summaryrefslogtreecommitdiff
path: root/builtin/ls-files.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/ls-files.c')
-rw-r--r--builtin/ls-files.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index e791b65..779dc18 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -11,6 +11,7 @@
#include "quote.h"
#include "dir.h"
#include "builtin.h"
+#include "strbuf.h"
#include "tree.h"
#include "cache-tree.h"
#include "parse-options.h"
@@ -48,6 +49,7 @@ static char *ps_matched;
static const char *with_tree;
static int exc_given;
static int exclude_args;
+static const char *format;
static const char *tag_cached = "";
static const char *tag_unmerged = "";
@@ -85,6 +87,16 @@ static void write_name(const char *name)
stdout, line_terminator);
}
+static void write_name_to_buf(struct strbuf *sb, const char *name)
+{
+ const char *rel = relative_path(name, prefix_len ? prefix : NULL, sb);
+
+ if (line_terminator)
+ quote_c_style(rel, sb, NULL, 0);
+ else
+ strbuf_addstr(sb, rel);
+}
+
static const char *get_tag(const struct cache_entry *ce, const char *tag)
{
static char alttag[4];
@@ -222,6 +234,73 @@ static void show_submodule(struct repository *superproject,
repo_clear(&subrepo);
}
+struct show_index_data {
+ const char *pathname;
+ struct index_state *istate;
+ const struct cache_entry *ce;
+};
+
+static size_t expand_show_index(struct strbuf *sb, const char *start,
+ void *context)
+{
+ struct show_index_data *data = context;
+ const char *end;
+ const char *p;
+ size_t len = strbuf_expand_literal_cb(sb, start, NULL);
+ struct stat st;
+
+ if (len)
+ return len;
+ if (*start != '(')
+ die(_("bad ls-files format: element '%s' "
+ "does not start with '('"), start);
+
+ end = strchr(start + 1, ')');
+ if (!end)
+ die(_("bad ls-files format: element '%s'"
+ "does not end in ')'"), start);
+
+ len = end - start + 1;
+ if (skip_prefix(start, "(objectmode)", &p))
+ strbuf_addf(sb, "%06o", data->ce->ce_mode);
+ else if (skip_prefix(start, "(objectname)", &p))
+ strbuf_add_unique_abbrev(sb, &data->ce->oid, abbrev);
+ else if (skip_prefix(start, "(stage)", &p))
+ strbuf_addf(sb, "%d", ce_stage(data->ce));
+ else if (skip_prefix(start, "(eolinfo:index)", &p))
+ strbuf_addstr(sb, S_ISREG(data->ce->ce_mode) ?
+ get_cached_convert_stats_ascii(data->istate,
+ data->ce->name) : "");
+ else if (skip_prefix(start, "(eolinfo:worktree)", &p))
+ strbuf_addstr(sb, !lstat(data->pathname, &st) &&
+ S_ISREG(st.st_mode) ?
+ get_wt_convert_stats_ascii(data->pathname) : "");
+ else if (skip_prefix(start, "(eolattr)", &p))
+ strbuf_addstr(sb, get_convert_attr_ascii(data->istate,
+ data->pathname));
+ else if (skip_prefix(start, "(path)", &p))
+ write_name_to_buf(sb, data->pathname);
+ else
+ die(_("bad ls-files format: %%%.*s"), (int)len, start);
+
+ return len;
+}
+
+static void show_ce_fmt(struct repository *repo, const struct cache_entry *ce,
+ const char *format, const char *fullname) {
+ struct show_index_data data = {
+ .pathname = fullname,
+ .istate = repo->index,
+ .ce = ce,
+ };
+ struct strbuf sb = STRBUF_INIT;
+
+ strbuf_expand(&sb, format, expand_show_index, &data);
+ strbuf_addch(&sb, line_terminator);
+ fwrite(sb.buf, sb.len, 1, stdout);
+ strbuf_release(&sb);
+}
+
static void show_ce(struct repository *repo, struct dir_struct *dir,
const struct cache_entry *ce, const char *fullname,
const char *tag)
@@ -236,6 +315,12 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,
max_prefix_len, ps_matched,
S_ISDIR(ce->ce_mode) ||
S_ISGITLINK(ce->ce_mode))) {
+ if (format) {
+ show_ce_fmt(repo, ce, format, fullname);
+ print_debug(ce);
+ return;
+ }
+
tag = get_tag(ce, tag);
if (!show_stage) {
@@ -675,6 +760,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
N_("suppress duplicate entries")),
OPT_BOOL(0, "sparse", &show_sparse_dirs,
N_("show sparse directories in the presence of a sparse index")),
+ OPT_STRING_F(0, "format", &format, N_("format"),
+ N_("format to use for the output"),
+ PARSE_OPT_NONEG),
OPT_END()
};
int ret = 0;
@@ -699,6 +787,13 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
for (i = 0; i < exclude_list.nr; i++) {
add_pattern(exclude_list.items[i].string, "", 0, pl, --exclude_args);
}
+
+ if (format && (show_stage || show_others || show_killed ||
+ show_resolve_undo || skipping_duplicates || show_eol || show_tag))
+ usage_msg_opt(_("--format cannot be used with -s, -o, -k, -t, "
+ "--resolve-undo, --deduplicate, --eol"),
+ ls_files_usage, builtin_ls_files_options);
+
if (show_tag || show_valid_bit || show_fsmonitor_bit) {
tag_cached = "H ";
tag_unmerged = "M ";