11
11
#include "quote.h"
12
12
#include "dir.h"
13
13
#include "builtin.h"
14
+ #include "strbuf.h"
14
15
#include "tree.h"
15
16
#include "cache-tree.h"
16
17
#include "parse-options.h"
@@ -48,6 +49,7 @@ static char *ps_matched;
48
49
static const char * with_tree ;
49
50
static int exc_given ;
50
51
static int exclude_args ;
52
+ static const char * format ;
51
53
52
54
static const char * tag_cached = "" ;
53
55
static const char * tag_unmerged = "" ;
@@ -85,6 +87,16 @@ static void write_name(const char *name)
85
87
stdout , line_terminator );
86
88
}
87
89
90
+ static void write_name_to_buf (struct strbuf * sb , const char * name )
91
+ {
92
+ const char * rel = relative_path (name , prefix_len ? prefix : NULL , sb );
93
+
94
+ if (line_terminator )
95
+ quote_c_style (rel , sb , NULL , 0 );
96
+ else
97
+ strbuf_addstr (sb , rel );
98
+ }
99
+
88
100
static const char * get_tag (const struct cache_entry * ce , const char * tag )
89
101
{
90
102
static char alttag [4 ];
@@ -222,6 +234,73 @@ static void show_submodule(struct repository *superproject,
222
234
repo_clear (& subrepo );
223
235
}
224
236
237
+ struct show_index_data {
238
+ const char * pathname ;
239
+ struct index_state * istate ;
240
+ const struct cache_entry * ce ;
241
+ };
242
+
243
+ static size_t expand_show_index (struct strbuf * sb , const char * start ,
244
+ void * context )
245
+ {
246
+ struct show_index_data * data = context ;
247
+ const char * end ;
248
+ const char * p ;
249
+ size_t len = strbuf_expand_literal_cb (sb , start , NULL );
250
+ struct stat st ;
251
+
252
+ if (len )
253
+ return len ;
254
+ if (* start != '(' )
255
+ die (_ ("bad ls-files format: element '%s' "
256
+ "does not start with '('" ), start );
257
+
258
+ end = strchr (start + 1 , ')' );
259
+ if (!end )
260
+ die (_ ("bad ls-files format: element '%s'"
261
+ "does not end in ')'" ), start );
262
+
263
+ len = end - start + 1 ;
264
+ if (skip_prefix (start , "(objectmode)" , & p ))
265
+ strbuf_addf (sb , "%06o" , data -> ce -> ce_mode );
266
+ else if (skip_prefix (start , "(objectname)" , & p ))
267
+ strbuf_add_unique_abbrev (sb , & data -> ce -> oid , abbrev );
268
+ else if (skip_prefix (start , "(stage)" , & p ))
269
+ strbuf_addf (sb , "%d" , ce_stage (data -> ce ));
270
+ else if (skip_prefix (start , "(eolinfo:index)" , & p ))
271
+ strbuf_addstr (sb , S_ISREG (data -> ce -> ce_mode ) ?
272
+ get_cached_convert_stats_ascii (data -> istate ,
273
+ data -> ce -> name ) : "" );
274
+ else if (skip_prefix (start , "(eolinfo:worktree)" , & p ))
275
+ strbuf_addstr (sb , !lstat (data -> pathname , & st ) &&
276
+ S_ISREG (st .st_mode ) ?
277
+ get_wt_convert_stats_ascii (data -> pathname ) : "" );
278
+ else if (skip_prefix (start , "(eolattr)" , & p ))
279
+ strbuf_addstr (sb , get_convert_attr_ascii (data -> istate ,
280
+ data -> pathname ));
281
+ else if (skip_prefix (start , "(path)" , & p ))
282
+ write_name_to_buf (sb , data -> pathname );
283
+ else
284
+ die (_ ("bad ls-files format: %%%.*s" ), (int )len , start );
285
+
286
+ return len ;
287
+ }
288
+
289
+ static void show_ce_fmt (struct repository * repo , const struct cache_entry * ce ,
290
+ const char * format , const char * fullname ) {
291
+ struct show_index_data data = {
292
+ .pathname = fullname ,
293
+ .istate = repo -> index ,
294
+ .ce = ce ,
295
+ };
296
+ struct strbuf sb = STRBUF_INIT ;
297
+
298
+ strbuf_expand (& sb , format , expand_show_index , & data );
299
+ strbuf_addch (& sb , line_terminator );
300
+ fwrite (sb .buf , sb .len , 1 , stdout );
301
+ strbuf_release (& sb );
302
+ }
303
+
225
304
static void show_ce (struct repository * repo , struct dir_struct * dir ,
226
305
const struct cache_entry * ce , const char * fullname ,
227
306
const char * tag )
@@ -236,6 +315,12 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,
236
315
max_prefix_len , ps_matched ,
237
316
S_ISDIR (ce -> ce_mode ) ||
238
317
S_ISGITLINK (ce -> ce_mode ))) {
318
+ if (format ) {
319
+ show_ce_fmt (repo , ce , format , fullname );
320
+ print_debug (ce );
321
+ return ;
322
+ }
323
+
239
324
tag = get_tag (ce , tag );
240
325
241
326
if (!show_stage ) {
@@ -675,6 +760,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
675
760
N_ ("suppress duplicate entries" )),
676
761
OPT_BOOL (0 , "sparse" , & show_sparse_dirs ,
677
762
N_ ("show sparse directories in the presence of a sparse index" )),
763
+ OPT_STRING_F (0 , "format" , & format , N_ ("format" ),
764
+ N_ ("format to use for the output" ),
765
+ PARSE_OPT_NONEG ),
678
766
OPT_END ()
679
767
};
680
768
int ret = 0 ;
@@ -699,6 +787,13 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
699
787
for (i = 0 ; i < exclude_list .nr ; i ++ ) {
700
788
add_pattern (exclude_list .items [i ].string , "" , 0 , pl , -- exclude_args );
701
789
}
790
+
791
+ if (format && (show_stage || show_others || show_killed ||
792
+ show_resolve_undo || skipping_duplicates || show_eol || show_tag ))
793
+ usage_msg_opt (_ ("--format cannot be used with -s, -o, -k, -t, "
794
+ "--resolve-undo, --deduplicate, --eol" ),
795
+ ls_files_usage , builtin_ls_files_options );
796
+
702
797
if (show_tag || show_valid_bit || show_fsmonitor_bit ) {
703
798
tag_cached = "H " ;
704
799
tag_unmerged = "M " ;
0 commit comments