blob: 1c0f057d02c55c8449bc9da1f1f01d509bbca8ba [file] [log] [blame]
Linus Torvalds8695c8b2005-04-11 18:55:38 -07001/*
2 * This merges the file listing in the directory cache index
3 * with the actual working directory list, and shows different
4 * combinations of the two.
5 *
6 * Copyright (C) Linus Torvalds, 2005
7 */
Linus Torvalds8695c8b2005-04-11 18:55:38 -07008#include "cache.h"
Junio C Hamano22ddf712005-10-14 21:56:46 -07009#include "quote.h"
Linus Torvalds453ec4b2006-05-16 19:02:14 -070010#include "dir.h"
Peter Eriksen0864f262006-05-23 14:15:29 +020011#include "builtin.h"
Junio C Hamano64586e72007-09-12 16:04:22 -070012#include "tree.h"
Miklos Vajnace8e8802009-02-17 15:27:11 +010013#include "parse-options.h"
Junio C Hamano9d9a2f42009-12-25 10:08:04 -080014#include "resolve-undo.h"
15#include "string-list.h"
Nguyễn Thái Ngọc Duy64acde92013-07-14 15:35:25 +070016#include "pathspec.h"
Brandon Williamse77aa332016-10-07 11:18:49 -070017#include "run-command.h"
Linus Torvalds8695c8b2005-04-11 18:55:38 -070018
David Rientjes96f1e582006-08-15 10:23:48 -070019static int abbrev;
20static int show_deleted;
21static int show_cached;
22static int show_others;
23static int show_stage;
24static int show_unmerged;
Junio C Hamano9d9a2f42009-12-25 10:08:04 -080025static int show_resolve_undo;
David Rientjes96f1e582006-08-15 10:23:48 -070026static int show_modified;
27static int show_killed;
28static int show_valid_bit;
Junio C Hamanob83c8342005-04-15 11:11:01 -070029static int line_terminator = '\n';
Thomas Rast84974212010-07-31 00:35:59 +020030static int debug_mode;
Torsten Bögershausena7630bd2016-01-16 07:50:02 +010031static int show_eol;
Brandon Williamse77aa332016-10-07 11:18:49 -070032static int recurse_submodules;
Brandon Williams07c01b92016-10-07 11:18:50 -070033static struct argv_array submodules_options = ARGV_ARRAY_INIT;
Linus Torvalds8695c8b2005-04-11 18:55:38 -070034
Clemens Buchacherefad1a52010-06-03 15:39:18 +020035static const char *prefix;
Brandon Williamse77aa332016-10-07 11:18:49 -070036static const char *super_prefix;
Clemens Buchacherefad1a52010-06-03 15:39:18 +020037static int max_prefix_len;
David Rientjes96f1e582006-08-15 10:23:48 -070038static int prefix_len;
Nguyễn Thái Ngọc Duy9e06d6e2013-07-14 15:35:43 +070039static struct pathspec pathspec;
David Rientjes96f1e582006-08-15 10:23:48 -070040static int error_unmatch;
41static char *ps_matched;
Junio C Hamano64586e72007-09-12 16:04:22 -070042static const char *with_tree;
Miklos Vajnace8e8802009-02-17 15:27:11 +010043static int exc_given;
Adam Spiersc04318e2013-01-06 16:58:04 +000044static int exclude_args;
Linus Torvalds5be4efb2005-08-21 12:55:33 -070045
Petr Baudis20d37ef2005-04-21 19:47:08 -070046static const char *tag_cached = "";
47static const char *tag_unmerged = "";
48static const char *tag_removed = "";
49static const char *tag_other = "";
Junio C Hamano6ca45942005-05-12 17:17:54 -070050static const char *tag_killed = "";
Junio C Hamanob0391892005-09-19 15:11:15 -070051static const char *tag_modified = "";
Nguyễn Thái Ngọc Duy44a36912009-08-20 20:46:57 +070052static const char *tag_skip_worktree = "";
Junio C Hamano9d9a2f42009-12-25 10:08:04 -080053static const char *tag_resolve_undo = "";
Petr Baudis20d37ef2005-04-21 19:47:08 -070054
Torsten Bögershausena7630bd2016-01-16 07:50:02 +010055static void write_eolinfo(const struct cache_entry *ce, const char *path)
56{
57 if (!show_eol)
58 return;
59 else {
60 struct stat st;
61 const char *i_txt = "";
62 const char *w_txt = "";
63 const char *a_txt = get_convert_attr_ascii(path);
64 if (ce && S_ISREG(ce->ce_mode))
65 i_txt = get_cached_convert_stats_ascii(ce->name);
66 if (!lstat(path, &st) && S_ISREG(st.st_mode))
67 w_txt = get_wt_convert_stats_ascii(path);
68 printf("i/%-5s w/%-5s attr/%-17s\t", i_txt, w_txt, a_txt);
69 }
70}
71
Jiang Xine9a820c2013-06-25 23:53:46 +080072static void write_name(const char *name)
Clemens Buchacherefad1a52010-06-03 15:39:18 +020073{
Jiang Xinad66df22013-06-25 23:53:44 +080074 /*
Brandon Williamse77aa332016-10-07 11:18:49 -070075 * Prepend the super_prefix to name to construct the full_name to be
76 * written.
77 */
78 struct strbuf full_name = STRBUF_INIT;
79 if (super_prefix) {
80 strbuf_addstr(&full_name, super_prefix);
81 strbuf_addstr(&full_name, name);
82 name = full_name.buf;
83 }
84
85 /*
Jiang Xine9a820c2013-06-25 23:53:46 +080086 * With "--full-name", prefix_len=0; this caller needs to pass
87 * an empty string in that case (a NULL is good for "").
Jiang Xinad66df22013-06-25 23:53:44 +080088 */
Jiang Xine9a820c2013-06-25 23:53:46 +080089 write_name_quoted_relative(name, prefix_len ? prefix : NULL,
90 stdout, line_terminator);
Brandon Williamse77aa332016-10-07 11:18:49 -070091
92 strbuf_release(&full_name);
Clemens Buchacherefad1a52010-06-03 15:39:18 +020093}
94
Linus Torvalds453ec4b2006-05-16 19:02:14 -070095static void show_dir_entry(const char *tag, struct dir_entry *ent)
Linus Torvalds5be4efb2005-08-21 12:55:33 -070096{
Clemens Buchacherefad1a52010-06-03 15:39:18 +020097 int len = max_prefix_len;
Linus Torvalds5be4efb2005-08-21 12:55:33 -070098
99 if (len >= ent->len)
Junio C Hamano7e44c932008-08-31 09:39:19 -0700100 die("git ls-files: internal error - directory entry not superset of prefix");
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700101
Nguyễn Thái Ngọc Duyebb32892014-01-24 20:40:29 +0700102 if (!dir_path_match(ent, &pathspec, len, ps_matched))
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700103 return;
104
Junio C Hamano22ddf712005-10-14 21:56:46 -0700105 fputs(tag, stdout);
Torsten Bögershausena7630bd2016-01-16 07:50:02 +0100106 write_eolinfo(NULL, ent->name);
Jiang Xine9a820c2013-06-25 23:53:46 +0800107 write_name(ent->name);
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700108}
109
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700110static void show_other_files(struct dir_struct *dir)
Junio C Hamanofcbc3082005-11-06 17:26:31 -0800111{
112 int i;
Linus Torvalds56984542007-04-14 16:22:08 -0700113
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700114 for (i = 0; i < dir->nr; i++) {
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700115 struct dir_entry *ent = dir->entries[i];
Jeff King98fa4732008-10-16 11:07:26 -0400116 if (!cache_name_is_other(ent->name, ent->len))
117 continue;
Junio C Hamanofcbc3082005-11-06 17:26:31 -0800118 show_dir_entry(tag_other, ent);
119 }
120}
121
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700122static void show_killed_files(struct dir_struct *dir)
Junio C Hamano6ca45942005-05-12 17:17:54 -0700123{
124 int i;
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700125 for (i = 0; i < dir->nr; i++) {
126 struct dir_entry *ent = dir->entries[i];
Junio C Hamano6ca45942005-05-12 17:17:54 -0700127 char *cp, *sp;
128 int pos, len, killed = 0;
129
130 for (cp = ent->name; cp - ent->name < ent->len; cp = sp + 1) {
131 sp = strchr(cp, '/');
132 if (!sp) {
133 /* If ent->name is prefix of an entry in the
134 * cache, it will be killed.
135 */
136 pos = cache_name_pos(ent->name, ent->len);
137 if (0 <= pos)
Johannes Schindelinef1177d12016-07-26 18:05:50 +0200138 die("BUG: killed-file %.*s not found",
139 ent->len, ent->name);
Junio C Hamano6ca45942005-05-12 17:17:54 -0700140 pos = -pos - 1;
141 while (pos < active_nr &&
142 ce_stage(active_cache[pos]))
143 pos++; /* skip unmerged */
144 if (active_nr <= pos)
145 break;
146 /* pos points at a name immediately after
147 * ent->name in the cache. Does it expect
148 * ent->name to be a directory?
149 */
150 len = ce_namelen(active_cache[pos]);
151 if ((ent->len < len) &&
152 !strncmp(active_cache[pos]->name,
153 ent->name, ent->len) &&
154 active_cache[pos]->name[ent->len] == '/')
155 killed = 1;
156 break;
157 }
158 if (0 <= cache_name_pos(ent->name, sp - ent->name)) {
159 /* If any of the leading directories in
160 * ent->name is registered in the cache,
161 * ent->name will be killed.
162 */
163 killed = 1;
164 break;
165 }
166 }
167 if (killed)
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700168 show_dir_entry(tag_killed, dir->entries[i]);
Junio C Hamano6ca45942005-05-12 17:17:54 -0700169 }
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700170}
171
Brandon Williams07c01b92016-10-07 11:18:50 -0700172/*
173 * Compile an argv_array with all of the options supported by --recurse_submodules
174 */
175static void compile_submodule_options(const struct dir_struct *dir, int show_tag)
176{
177 if (line_terminator == '\0')
178 argv_array_push(&submodules_options, "-z");
179 if (show_tag)
180 argv_array_push(&submodules_options, "-t");
181 if (show_valid_bit)
182 argv_array_push(&submodules_options, "-v");
183 if (show_cached)
184 argv_array_push(&submodules_options, "--cached");
185 if (show_eol)
186 argv_array_push(&submodules_options, "--eol");
187 if (debug_mode)
188 argv_array_push(&submodules_options, "--debug");
189}
190
Brandon Williamse77aa332016-10-07 11:18:49 -0700191/**
192 * Recursively call ls-files on a submodule
193 */
194static void show_gitlink(const struct cache_entry *ce)
195{
196 struct child_process cp = CHILD_PROCESS_INIT;
197 int status;
Brandon Williams75a63152016-10-07 11:18:51 -0700198 int i;
Brandon Williamse77aa332016-10-07 11:18:49 -0700199
200 argv_array_pushf(&cp.args, "--super-prefix=%s%s/",
201 super_prefix ? super_prefix : "",
202 ce->name);
203 argv_array_push(&cp.args, "ls-files");
204 argv_array_push(&cp.args, "--recurse-submodules");
205
Brandon Williams07c01b92016-10-07 11:18:50 -0700206 /* add supported options */
207 argv_array_pushv(&cp.args, submodules_options.argv);
208
Brandon Williams75a63152016-10-07 11:18:51 -0700209 /*
210 * Pass in the original pathspec args. The submodule will be
211 * responsible for prepending the 'submodule_prefix' prior to comparing
212 * against the pathspec for matches.
213 */
214 argv_array_push(&cp.args, "--");
215 for (i = 0; i < pathspec.nr; i++)
216 argv_array_push(&cp.args, pathspec.items[i].original);
217
Brandon Williamse77aa332016-10-07 11:18:49 -0700218 cp.git_cmd = 1;
219 cp.dir = ce->name;
220 status = run_command(&cp);
221 if (status)
222 exit(status);
223}
224
Nguyễn Thái Ngọc Duy9c5e6c82013-07-09 22:29:00 +0700225static void show_ce_entry(const char *tag, const struct cache_entry *ce)
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700226{
Brandon Williamse77aa332016-10-07 11:18:49 -0700227 struct strbuf name = STRBUF_INIT;
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200228 int len = max_prefix_len;
Brandon Williamse77aa332016-10-07 11:18:49 -0700229 if (super_prefix)
230 strbuf_addstr(&name, super_prefix);
231 strbuf_addstr(&name, ce->name);
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700232
233 if (len >= ce_namelen(ce))
Junio C Hamano7e44c932008-08-31 09:39:19 -0700234 die("git ls-files: internal error - cache entry not superset of prefix");
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700235
Brandon Williams75a63152016-10-07 11:18:51 -0700236 if (recurse_submodules && S_ISGITLINK(ce->ce_mode) &&
237 submodule_path_match(&pathspec, name.buf, ps_matched)) {
Brandon Williamse77aa332016-10-07 11:18:49 -0700238 show_gitlink(ce);
239 } else if (match_pathspec(&pathspec, name.buf, name.len,
240 len, ps_matched,
241 S_ISDIR(ce->ce_mode) ||
242 S_ISGITLINK(ce->ce_mode))) {
243 if (tag && *tag && show_valid_bit &&
244 (ce->ce_flags & CE_VALID)) {
245 static char alttag[4];
246 memcpy(alttag, tag, 3);
247 if (isalpha(tag[0]))
248 alttag[0] = tolower(tag[0]);
249 else if (tag[0] == '?')
250 alttag[0] = '!';
251 else {
252 alttag[0] = 'v';
253 alttag[1] = tag[0];
254 alttag[2] = ' ';
255 alttag[3] = 0;
256 }
257 tag = alttag;
Junio C Hamano2bcab242006-02-08 21:50:18 -0800258 }
Brandon Williamse77aa332016-10-07 11:18:49 -0700259
260 if (!show_stage) {
261 fputs(tag, stdout);
262 } else {
263 printf("%s%06o %s %d\t",
264 tag,
265 ce->ce_mode,
Junio C Hamano1c2b1f72016-10-26 13:14:44 -0700266 find_unique_abbrev(ce->oid.hash, abbrev),
Brandon Williamse77aa332016-10-07 11:18:49 -0700267 ce_stage(ce));
268 }
269 write_eolinfo(ce, ce->name);
270 write_name(ce->name);
271 if (debug_mode) {
272 const struct stat_data *sd = &ce->ce_stat_data;
273
274 printf(" ctime: %d:%d\n", sd->sd_ctime.sec, sd->sd_ctime.nsec);
275 printf(" mtime: %d:%d\n", sd->sd_mtime.sec, sd->sd_mtime.nsec);
276 printf(" dev: %d\tino: %d\n", sd->sd_dev, sd->sd_ino);
277 printf(" uid: %d\tgid: %d\n", sd->sd_uid, sd->sd_gid);
278 printf(" size: %d\tflags: %x\n", sd->sd_size, ce->ce_flags);
279 }
Junio C Hamano2bcab242006-02-08 21:50:18 -0800280 }
281
Brandon Williamse77aa332016-10-07 11:18:49 -0700282 strbuf_release(&name);
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700283}
284
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200285static void show_ru_info(void)
Junio C Hamano9d9a2f42009-12-25 10:08:04 -0800286{
Alex Riesen8a57c6e2010-07-03 14:41:54 +0200287 struct string_list_item *item;
288
Junio C Hamano9d9a2f42009-12-25 10:08:04 -0800289 if (!the_index.resolve_undo)
290 return;
Alex Riesen8a57c6e2010-07-03 14:41:54 +0200291
292 for_each_string_list_item(item, the_index.resolve_undo) {
293 const char *path = item->string;
294 struct resolve_undo_info *ui = item->util;
295 int i, len;
296
297 len = strlen(path);
298 if (len < max_prefix_len)
299 continue; /* outside of the prefix */
Nguyễn Thái Ngọc Duy854b0952014-01-24 20:40:30 +0700300 if (!match_pathspec(&pathspec, path, len,
Nguyễn Thái Ngọc Duyae8d0822014-01-24 20:40:33 +0700301 max_prefix_len, ps_matched, 0))
Alex Riesen8a57c6e2010-07-03 14:41:54 +0200302 continue; /* uninterested */
303 for (i = 0; i < 3; i++) {
304 if (!ui->mode[i])
305 continue;
306 printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
307 find_unique_abbrev(ui->sha1[i], abbrev),
308 i + 1);
Jiang Xine9a820c2013-06-25 23:53:46 +0800309 write_name(path);
Alex Riesen8a57c6e2010-07-03 14:41:54 +0200310 }
311 }
Junio C Hamano9d9a2f42009-12-25 10:08:04 -0800312}
313
Nguyễn Thái Ngọc Duy9c5e6c82013-07-09 22:29:00 +0700314static int ce_excluded(struct dir_struct *dir, const struct cache_entry *ce)
Junio C Hamano782cd4c2012-06-05 21:17:52 -0700315{
316 int dtype = ce_to_dtype(ce);
Karsten Bleesb07bc8c2013-04-15 21:12:57 +0200317 return is_excluded(dir, ce->name, &dtype);
Junio C Hamano782cd4c2012-06-05 21:17:52 -0700318}
319
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200320static void show_files(struct dir_struct *dir)
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700321{
322 int i;
323
324 /* For cached/deleted files we don't need to even do the readdir */
Junio C Hamano6ca45942005-05-12 17:17:54 -0700325 if (show_others || show_killed) {
Junio C Hamano2eac2a42013-08-15 12:13:46 -0700326 if (!show_others)
327 dir->flags |= DIR_COLLECT_KILLED_ONLY;
Nguyễn Thái Ngọc Duy7327d3d2013-07-14 15:35:55 +0700328 fill_directory(dir, &pathspec);
Junio C Hamano6ca45942005-05-12 17:17:54 -0700329 if (show_others)
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700330 show_other_files(dir);
Junio C Hamano6ca45942005-05-12 17:17:54 -0700331 if (show_killed)
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700332 show_killed_files(dir);
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700333 }
René Scharfe0b437a12013-06-13 20:19:44 +0200334 if (show_cached || show_stage) {
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700335 for (i = 0; i < active_nr; i++) {
Nguyễn Thái Ngọc Duy9c5e6c82013-07-09 22:29:00 +0700336 const struct cache_entry *ce = active_cache[i];
Junio C Hamanoeb417752012-06-01 11:28:00 -0700337 if ((dir->flags & DIR_SHOW_IGNORED) &&
Karsten Bleesb07bc8c2013-04-15 21:12:57 +0200338 !ce_excluded(dir, ce))
Jeff King500348a2009-10-30 15:05:52 -0400339 continue;
Linus Torvaldseec8c632005-04-16 12:43:32 -0700340 if (show_unmerged && !ce_stage(ce))
341 continue;
Linus Torvalds7a51ed62008-01-14 16:03:17 -0800342 if (ce->ce_flags & CE_UPDATE)
Junio C Hamano64586e72007-09-12 16:04:22 -0700343 continue;
Nguyễn Thái Ngọc Duy44a36912009-08-20 20:46:57 +0700344 show_ce_entry(ce_stage(ce) ? tag_unmerged :
345 (ce_skip_worktree(ce) ? tag_skip_worktree : tag_cached), ce);
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700346 }
347 }
René Scharfe0b437a12013-06-13 20:19:44 +0200348 if (show_deleted || show_modified) {
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700349 for (i = 0; i < active_nr; i++) {
Nguyễn Thái Ngọc Duy9c5e6c82013-07-09 22:29:00 +0700350 const struct cache_entry *ce = active_cache[i];
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700351 struct stat st;
Junio C Hamanob0391892005-09-19 15:11:15 -0700352 int err;
Junio C Hamanoeb417752012-06-01 11:28:00 -0700353 if ((dir->flags & DIR_SHOW_IGNORED) &&
Karsten Bleesb07bc8c2013-04-15 21:12:57 +0200354 !ce_excluded(dir, ce))
Jeff King500348a2009-10-30 15:05:52 -0400355 continue;
Junio C Hamano4b4e26d2008-11-16 00:10:25 -0800356 if (ce->ce_flags & CE_UPDATE)
357 continue;
Nguyễn Thái Ngọc Duyb4d16902009-08-20 20:46:58 +0700358 if (ce_skip_worktree(ce))
359 continue;
Junio C Hamanob0391892005-09-19 15:11:15 -0700360 err = lstat(ce->name, &st);
361 if (show_deleted && err)
362 show_ce_entry(tag_removed, ce);
Junio C Hamano2bcab242006-02-08 21:50:18 -0800363 if (show_modified && ce_modified(ce, &st, 0))
Junio C Hamanob0391892005-09-19 15:11:15 -0700364 show_ce_entry(tag_modified, ce);
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700365 }
366 }
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700367}
368
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700369/*
370 * Prune the index to only contain stuff starting with "prefix"
371 */
René Scharfe7b4158a2017-02-10 20:42:28 +0100372static void prune_cache(const char *prefix, size_t prefixlen)
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700373{
René Scharfe7b4158a2017-02-10 20:42:28 +0100374 int pos;
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700375 unsigned int first, last;
376
René Scharfe7b4158a2017-02-10 20:42:28 +0100377 if (!prefix)
378 return;
379 pos = cache_name_pos(prefix, prefixlen);
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700380 if (pos < 0)
381 pos = -pos-1;
René Scharfe96f6d3f2017-02-10 21:03:30 +0100382 first = pos;
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700383 last = active_nr;
384 while (last > first) {
385 int next = (last + first) >> 1;
Nguyễn Thái Ngọc Duy9c5e6c82013-07-09 22:29:00 +0700386 const struct cache_entry *ce = active_cache[next];
René Scharfe7b4158a2017-02-10 20:42:28 +0100387 if (!strncmp(ce->name, prefix, prefixlen)) {
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700388 first = next+1;
389 continue;
390 }
391 last = next;
392 }
René Scharfe96f6d3f2017-02-10 21:03:30 +0100393 memmove(active_cache, active_cache + pos,
394 (last - pos) * sizeof(struct cache_entry *));
395 active_nr = last - pos;
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700396}
397
Junio C Hamano64586e72007-09-12 16:04:22 -0700398/*
399 * Read the tree specified with --with-tree option
400 * (typically, HEAD) into stage #1 and then
401 * squash them down to stage #0. This is used for
402 * --error-unmatch to list and check the path patterns
403 * that were given from the command line. We are not
404 * going to write this index out.
405 */
Junio C Hamanoee425e42007-11-18 01:13:32 -0800406void overlay_tree_on_cache(const char *tree_name, const char *prefix)
Junio C Hamano64586e72007-09-12 16:04:22 -0700407{
408 struct tree *tree;
409 unsigned char sha1[20];
Nguyễn Thái Ngọc Duyf0096c02011-03-25 16:34:19 +0700410 struct pathspec pathspec;
Junio C Hamano64586e72007-09-12 16:04:22 -0700411 struct cache_entry *last_stage0 = NULL;
412 int i;
413
414 if (get_sha1(tree_name, sha1))
415 die("tree-ish %s not found.", tree_name);
416 tree = parse_tree_indirect(sha1);
417 if (!tree)
418 die("bad tree-ish %s", tree_name);
419
420 /* Hoist the unmerged entries up to stage #3 to make room */
421 for (i = 0; i < active_nr; i++) {
422 struct cache_entry *ce = active_cache[i];
423 if (!ce_stage(ce))
424 continue;
Linus Torvalds7a51ed62008-01-14 16:03:17 -0800425 ce->ce_flags |= CE_STAGEMASK;
Junio C Hamano64586e72007-09-12 16:04:22 -0700426 }
427
428 if (prefix) {
Nguyễn Thái Ngọc Duy9a087272013-07-14 15:35:59 +0700429 static const char *(matchbuf[1]);
430 matchbuf[0] = NULL;
431 parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC,
432 PATHSPEC_PREFER_CWD, prefix, matchbuf);
Junio C Hamano64586e72007-09-12 16:04:22 -0700433 } else
Nguyễn Thái Ngọc Duy9a087272013-07-14 15:35:59 +0700434 memset(&pathspec, 0, sizeof(pathspec));
Nguyễn Thái Ngọc Duyf0096c02011-03-25 16:34:19 +0700435 if (read_tree(tree, 1, &pathspec))
Junio C Hamano64586e72007-09-12 16:04:22 -0700436 die("unable to read tree entries %s", tree_name);
437
438 for (i = 0; i < active_nr; i++) {
439 struct cache_entry *ce = active_cache[i];
440 switch (ce_stage(ce)) {
441 case 0:
442 last_stage0 = ce;
443 /* fallthru */
444 default:
445 continue;
446 case 1:
447 /*
448 * If there is stage #0 entry for this, we do not
449 * need to show it. We use CE_UPDATE bit to mark
450 * such an entry.
451 */
452 if (last_stage0 &&
453 !strcmp(last_stage0->name, ce->name))
Linus Torvalds7a51ed62008-01-14 16:03:17 -0800454 ce->ce_flags |= CE_UPDATE;
Junio C Hamano64586e72007-09-12 16:04:22 -0700455 }
456 }
457}
458
Miklos Vajnace8e8802009-02-17 15:27:11 +0100459static const char * const ls_files_usage[] = {
Alex Henrie9c9b4f22015-01-13 00:44:47 -0700460 N_("git ls-files [<options>] [<file>...]"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100461 NULL
462};
463
Miklos Vajnace8e8802009-02-17 15:27:11 +0100464static int option_parse_exclude(const struct option *opt,
465 const char *arg, int unset)
466{
Adam Spiers72aeb182013-01-16 13:25:58 +0000467 struct string_list *exclude_list = opt->value;
Miklos Vajnace8e8802009-02-17 15:27:11 +0100468
469 exc_given = 1;
Adam Spiers72aeb182013-01-16 13:25:58 +0000470 string_list_append(exclude_list, arg);
Miklos Vajnace8e8802009-02-17 15:27:11 +0100471
472 return 0;
473}
474
475static int option_parse_exclude_from(const struct option *opt,
476 const char *arg, int unset)
477{
478 struct dir_struct *dir = opt->value;
479
480 exc_given = 1;
481 add_excludes_from_file(dir, arg);
482
483 return 0;
484}
485
486static int option_parse_exclude_standard(const struct option *opt,
487 const char *arg, int unset)
488{
489 struct dir_struct *dir = opt->value;
490
491 exc_given = 1;
492 setup_standard_excludes(dir);
493
494 return 0;
495}
Nicolas Pitrecf9a1132005-04-28 15:06:25 -0700496
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200497int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700498{
Adam Spiers72aeb182013-01-16 13:25:58 +0000499 int require_work_tree = 0, show_tag = 0, i;
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200500 const char *max_prefix;
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700501 struct dir_struct dir;
Adam Spiers72aeb182013-01-16 13:25:58 +0000502 struct exclude_list *el;
503 struct string_list exclude_list = STRING_LIST_INIT_NODUP;
Miklos Vajnace8e8802009-02-17 15:27:11 +0100504 struct option builtin_ls_files_options[] = {
Jeff King1f3c79a2016-01-31 06:35:46 -0500505 /* Think twice before adding "--nul" synonym to this */
506 OPT_SET_INT('z', NULL, &line_terminator,
507 N_("paths are separated with NUL character"), '\0'),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200508 OPT_BOOL('t', NULL, &show_tag,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700509 N_("identify the file status with tags")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200510 OPT_BOOL('v', NULL, &show_valid_bit,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700511 N_("use lowercase letters for 'assume unchanged' files")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200512 OPT_BOOL('c', "cached", &show_cached,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700513 N_("show cached files in the output (default)")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200514 OPT_BOOL('d', "deleted", &show_deleted,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700515 N_("show deleted files in the output")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200516 OPT_BOOL('m', "modified", &show_modified,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700517 N_("show modified files in the output")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200518 OPT_BOOL('o', "others", &show_others,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700519 N_("show other files in the output")),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100520 OPT_BIT('i', "ignored", &dir.flags,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700521 N_("show ignored files in the output"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100522 DIR_SHOW_IGNORED),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200523 OPT_BOOL('s', "stage", &show_stage,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700524 N_("show staged contents' object name in the output")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200525 OPT_BOOL('k', "killed", &show_killed,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700526 N_("show files on the filesystem that need to be removed")),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100527 OPT_BIT(0, "directory", &dir.flags,
Alex Henriead5fe372014-08-30 13:56:01 -0600528 N_("show 'other' directories' names only"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100529 DIR_SHOW_OTHER_DIRECTORIES),
Torsten Bögershausena7630bd2016-01-16 07:50:02 +0100530 OPT_BOOL(0, "eol", &show_eol, N_("show line endings of files")),
Jeff Kinge9008b92009-05-08 01:01:17 -0400531 OPT_NEGBIT(0, "empty-directory", &dir.flags,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700532 N_("don't show empty directories"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100533 DIR_HIDE_EMPTY_DIRECTORIES),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200534 OPT_BOOL('u', "unmerged", &show_unmerged,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700535 N_("show unmerged files in the output")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200536 OPT_BOOL(0, "resolve-undo", &show_resolve_undo,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700537 N_("show resolve-undo information")),
Junio C Hamanoa39b15b2013-01-23 21:19:10 -0800538 { OPTION_CALLBACK, 'x', "exclude", &exclude_list, N_("pattern"),
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700539 N_("skip files matching pattern"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100540 0, option_parse_exclude },
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700541 { OPTION_CALLBACK, 'X', "exclude-from", &dir, N_("file"),
542 N_("exclude patterns are read from <file>"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100543 0, option_parse_exclude_from },
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700544 OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, N_("file"),
545 N_("read additional per-directory exclude patterns in <file>")),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100546 { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700547 N_("add the standard git exclusions"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100548 PARSE_OPT_NOARG, option_parse_exclude_standard },
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200549 { OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700550 N_("make the output relative to the project top directory"),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100551 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
Brandon Williamse77aa332016-10-07 11:18:49 -0700552 OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
553 N_("recurse through submodules")),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200554 OPT_BOOL(0, "error-unmatch", &error_unmatch,
Nguyễn Thái Ngọc Duy377adc32012-08-20 19:32:20 +0700555 N_("if any <file> is not in the index, treat this as an error")),
556 OPT_STRING(0, "with-tree", &with_tree, N_("tree-ish"),
557 N_("pretend that paths removed since <tree-ish> are still present")),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100558 OPT__ABBREV(&abbrev),
Stefan Bellerd5d09d42013-08-03 13:51:19 +0200559 OPT_BOOL(0, "debug", &debug_mode, N_("show debugging data")),
Miklos Vajnace8e8802009-02-17 15:27:11 +0100560 OPT_END()
561 };
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700562
Nguyễn Thái Ngọc Duycbb31672010-10-22 01:48:14 -0500563 if (argc == 2 && !strcmp(argv[1], "-h"))
564 usage_with_options(ls_files_usage, builtin_ls_files_options);
565
Linus Torvalds453ec4b2006-05-16 19:02:14 -0700566 memset(&dir, 0, sizeof(dir));
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200567 prefix = cmd_prefix;
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700568 if (prefix)
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200569 prefix_len = strlen(prefix);
Brandon Williamse77aa332016-10-07 11:18:49 -0700570 super_prefix = get_super_prefix();
Johannes Schindelinef90d6d2008-05-14 18:46:53 +0100571 git_config(git_default_config, NULL);
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700572
Nguyễn Thái Ngọc Duyc28b3d62009-08-20 20:47:01 +0700573 if (read_cache() < 0)
574 die("index file corrupt");
575
Stephen Boyd37782922009-05-23 11:53:12 -0700576 argc = parse_options(argc, argv, prefix, builtin_ls_files_options,
Miklos Vajnace8e8802009-02-17 15:27:11 +0100577 ls_files_usage, 0);
Adam Spiers72aeb182013-01-16 13:25:58 +0000578 el = add_exclude_list(&dir, EXC_CMDL, "--exclude option");
579 for (i = 0; i < exclude_list.nr; i++) {
580 add_exclude(exclude_list.items[i].string, "", 0, el, --exclude_args);
581 }
Miklos Vajnace8e8802009-02-17 15:27:11 +0100582 if (show_tag || show_valid_bit) {
583 tag_cached = "H ";
584 tag_unmerged = "M ";
585 tag_removed = "R ";
586 tag_modified = "C ";
587 tag_other = "? ";
588 tag_killed = "K ";
Nguyễn Thái Ngọc Duy44a36912009-08-20 20:46:57 +0700589 tag_skip_worktree = "S ";
Junio C Hamano9d9a2f42009-12-25 10:08:04 -0800590 tag_resolve_undo = "U ";
Nicolas Pitre9ff768e2005-04-28 11:44:04 -0700591 }
Junio C Hamanode2e3b02009-03-20 14:30:51 -0700592 if (show_modified || show_others || show_deleted || (dir.flags & DIR_SHOW_IGNORED) || show_killed)
Miklos Vajnace8e8802009-02-17 15:27:11 +0100593 require_work_tree = 1;
594 if (show_unmerged)
595 /*
596 * There's no point in showing unmerged unless
597 * you also show the stage information.
598 */
599 show_stage = 1;
600 if (dir.exclude_per_dir)
601 exc_given = 1;
Nicolas Pitre9ff768e2005-04-28 11:44:04 -0700602
Mike Hommey7d8ae932007-11-03 12:23:12 +0100603 if (require_work_tree && !is_inside_work_tree())
604 setup_work_tree();
Johannes Schindelin6d9ba672007-01-23 13:30:20 +0100605
Brandon Williams07c01b92016-10-07 11:18:50 -0700606 if (recurse_submodules)
607 compile_submodule_options(&dir, show_tag);
608
Brandon Williamse77aa332016-10-07 11:18:49 -0700609 if (recurse_submodules &&
610 (show_stage || show_deleted || show_others || show_unmerged ||
Brandon Williams07c01b92016-10-07 11:18:50 -0700611 show_killed || show_modified || show_resolve_undo || with_tree))
Brandon Williamse77aa332016-10-07 11:18:49 -0700612 die("ls-files --recurse-submodules unsupported mode");
613
614 if (recurse_submodules && error_unmatch)
615 die("ls-files --recurse-submodules does not support "
616 "--error-unmatch");
617
Nguyễn Thái Ngọc Duy9e06d6e2013-07-14 15:35:43 +0700618 parse_pathspec(&pathspec, 0,
619 PATHSPEC_PREFER_CWD |
620 PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
621 prefix, argv);
Johannes Schindelinf3670a52009-02-07 14:43:03 +0100622
Brandon Williams75a63152016-10-07 11:18:51 -0700623 /*
624 * Find common prefix for all pathspec's
625 * This is used as a performance optimization which unfortunately cannot
626 * be done when recursing into submodules
627 */
628 if (recurse_submodules)
629 max_prefix = NULL;
630 else
631 max_prefix = common_prefix(&pathspec);
Clemens Buchacher8894d532011-07-30 19:13:47 +0200632 max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
Linus Torvalds5be4efb2005-08-21 12:55:33 -0700633
Junio C Hamanobba319b2006-02-14 12:40:20 -0800634 /* Treat unmatching pathspec elements as errors */
Nguyễn Thái Ngọc Duy9e06d6e2013-07-14 15:35:43 +0700635 if (pathspec.nr && error_unmatch)
Junio C Hamano8b54c232015-08-20 09:57:32 -0700636 ps_matched = xcalloc(pathspec.nr, 1);
Junio C Hamanobba319b2006-02-14 12:40:20 -0800637
Ben Waltonac78b002009-10-08 21:53:35 -0400638 if ((dir.flags & DIR_SHOW_IGNORED) && !exc_given)
639 die("ls-files --ignored needs some exclude pattern");
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700640
641 /* With no flags, we default to showing the cached files */
René Scharfe0b437a12013-06-13 20:19:44 +0200642 if (!(show_stage || show_deleted || show_others || show_unmerged ||
643 show_killed || show_modified || show_resolve_undo))
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700644 show_cached = 1;
645
René Scharfe7b4158a2017-02-10 20:42:28 +0100646 prune_cache(max_prefix, max_prefix_len);
Junio C Hamano64586e72007-09-12 16:04:22 -0700647 if (with_tree) {
648 /*
649 * Basic sanity check; show-stages and show-unmerged
650 * would not make any sense with this option.
651 */
652 if (show_stage || show_unmerged)
653 die("ls-files --with-tree is incompatible with -s or -u");
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200654 overlay_tree_on_cache(with_tree, max_prefix);
Junio C Hamano64586e72007-09-12 16:04:22 -0700655 }
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200656 show_files(&dir);
Junio C Hamano9d9a2f42009-12-25 10:08:04 -0800657 if (show_resolve_undo)
Clemens Buchacherefad1a52010-06-03 15:39:18 +0200658 show_ru_info();
Junio C Hamanobba319b2006-02-14 12:40:20 -0800659
660 if (ps_matched) {
Junio C Hamanoee425e42007-11-18 01:13:32 -0800661 int bad;
Nguyễn Thái Ngọc Duy17ddc662013-07-14 15:35:53 +0700662 bad = report_path_error(ps_matched, &pathspec, prefix);
Junio C Hamanoee425e42007-11-18 01:13:32 -0800663 if (bad)
Andreas Ericssonced7b822006-11-30 12:28:28 +0100664 fprintf(stderr, "Did you forget to 'git add'?\n");
665
Junio C Hamanoee425e42007-11-18 01:13:32 -0800666 return bad ? 1 : 0;
Junio C Hamanobba319b2006-02-14 12:40:20 -0800667 }
668
Linus Torvalds8695c8b2005-04-11 18:55:38 -0700669 return 0;
670}