parse-opt: migrate builtin-ls-files.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Miklos Vajna committed
Feb 17, 2009 at 15:27 UTC
ce8e8804068772a24354ee24641ca65ffa417837
1 file changed
+120
-135
builtin-ls-files.c
+120
-135
@@ -10,6 +10,7 @@
10
#include "dir.h"
11
#include "builtin.h"
12
#include "tree.h"
13
+#include "parse-options.h"
14
15
static int abbrev;
16
static int show_deleted;
@@ -28,6 +29,7 @@ static const char **pathspec;
29
static int error_unmatch;
30
static char *ps_matched;
31
static const char *with_tree;
32
+static int exc_given;
33
34
static const char *tag_cached = "";
35
static const char *tag_unmerged = "";
@@ -376,156 +378,139 @@ int report_path_error(const char *ps_matched, const char **pathspec, int prefix_
378
return errors;
379
}
380
379
-static const char ls_files_usage[] =
380
- "git ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* "
381
- "[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] "
382
- "[ --exclude-per-directory=<filename> ] [--exclude-standard] "
383
- "[--full-name] [--abbrev] [--] [<file>]*";
381
+static const char * const ls_files_usage[] = {
382
+ "git ls-files [options] [<file>]*",
383
+ NULL
384
+};
385
+
386
+static int option_parse_z(const struct option *opt,
387
+ const char *arg, int unset)
388
+{
389
+ line_terminator = unset ? '\n' : '\0';
390
+
391
+ return 0;
392
+}
393
+
394
+static int option_parse_exclude(const struct option *opt,
395
+ const char *arg, int unset)
396
+{
397
+ struct exclude_list *list = opt->value;
398
+
399
+ exc_given = 1;
400
+ add_exclude(arg, "", 0, list);
401
+
402
+ return 0;
403
+}
404
+
405
+static int option_parse_exclude_from(const struct option *opt,
406
+ const char *arg, int unset)
407
+{
408
+ struct dir_struct *dir = opt->value;
409
+
410
+ exc_given = 1;
411
+ add_excludes_from_file(dir, arg);
412
+
413
+ return 0;
414
+}
415
+
416
+static int option_parse_exclude_standard(const struct option *opt,
417
+ const char *arg, int unset)
418
+{
419
+ struct dir_struct *dir = opt->value;
420
+
421
+ exc_given = 1;
422
+ setup_standard_excludes(dir);
423
+
424
+ return 0;
425
+}
426
427
int cmd_ls_files(int argc, const char **argv, const char *prefix)
428
{
387
- int i;
388
- int exc_given = 0, require_work_tree = 0;
429
+ int require_work_tree = 0, show_tag = 0;
430
struct dir_struct dir;
431
+ struct option builtin_ls_files_options[] = {
432
+ { OPTION_CALLBACK, 'z', NULL, NULL, NULL,
433
+ "paths are separated with NUL character",
434
+ PARSE_OPT_NOARG, option_parse_z },
435
+ OPT_BOOLEAN('t', NULL, &show_tag,
436
+ "identify the file status with tags"),
437
+ OPT_BOOLEAN('v', NULL, &show_valid_bit,
438
+ "use lowercase letters for 'assume unchanged' files"),
439
+ OPT_BOOLEAN('c', "cached", &show_cached,
440
+ "show cached files in the output (default)"),
441
+ OPT_BOOLEAN('d', "deleted", &show_deleted,
442
+ "show deleted files in the output"),
443
+ OPT_BOOLEAN('m', "modified", &show_modified,
444
+ "show modified files in the output"),
445
+ OPT_BOOLEAN('o', "others", &show_others,
446
+ "show other files in the output"),
447
+ OPT_BIT('i', "ignored", &dir.flags,
448
+ "show ignored files in the output",
449
+ DIR_SHOW_IGNORED),
450
+ OPT_BOOLEAN('s', "stage", &show_stage,
451
+ "show staged contents' object name in the output"),
452
+ OPT_BOOLEAN('k', "killed", &show_killed,
453
+ "show files on the filesystem that need to be removed"),
454
+ OPT_BIT(0, "directory", &dir.flags,
455
+ "show 'other' directories' name only",
456
+ DIR_SHOW_OTHER_DIRECTORIES),
457
+ OPT_BIT(0, "empty-directory", &dir.flags,
458
+ "list empty directories",
459
+ DIR_HIDE_EMPTY_DIRECTORIES),
460
+ OPT_BOOLEAN('u', "unmerged", &show_unmerged,
461
+ "show unmerged files in the output"),
462
+ { OPTION_CALLBACK, 'x', "exclude", &dir.exclude_list[EXC_CMDL], "pattern",
463
+ "skip files matching pattern",
464
+ 0, option_parse_exclude },
465
+ { OPTION_CALLBACK, 'X', "exclude-from", &dir, "file",
466
+ "exclude patterns are read from <file>",
467
+ 0, option_parse_exclude_from },
468
+ OPT_STRING(0, "exclude-per-directory", &dir.exclude_per_dir, "file",
469
+ "read additional per-directory exclude patterns in <file>"),
470
+ { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
471
+ "add the standard git exclusions",
472
+ PARSE_OPT_NOARG, option_parse_exclude_standard },
473
+ { OPTION_SET_INT, 0, "full-name", &prefix_offset, NULL,
474
+ "make the output relative to the project top directory",
475
+ PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
476
+ OPT_BOOLEAN(0, "error-unmatch", &error_unmatch,
477
+ "if any <file> is not in the index, treat this as an error"),
478
+ OPT_STRING(0, "with-tree", &with_tree, "tree-ish",
479
+ "pretend that paths removed since <tree-ish> are still present"),
480
+ OPT__ABBREV(&abbrev),
481
+ OPT_END()
482
+ };
483
484
memset(&dir, 0, sizeof(dir));
485
if (prefix)
486
prefix_offset = strlen(prefix);
487
git_config(git_default_config, NULL);
488
396
- for (i = 1; i < argc; i++) {
397
- const char *arg = argv[i];
398
-
399
- if (!strcmp(arg, "--")) {
400
- i++;
401
- break;
402
- }
403
- if (!strcmp(arg, "-z")) {
404
- line_terminator = 0;
405
- continue;
406
- }
407
- if (!strcmp(arg, "-t") || !strcmp(arg, "-v")) {
408
- tag_cached = "H ";
409
- tag_unmerged = "M ";
410
- tag_removed = "R ";
411
- tag_modified = "C ";
412
- tag_other = "? ";
413
- tag_killed = "K ";
414
- if (arg[1] == 'v')
415
- show_valid_bit = 1;
416
- continue;
417
- }
418
- if (!strcmp(arg, "-c") || !strcmp(arg, "--cached")) {
419
- show_cached = 1;
420
- continue;
421
- }
422
- if (!strcmp(arg, "-d") || !strcmp(arg, "--deleted")) {
423
- show_deleted = 1;
424
- continue;
425
- }
426
- if (!strcmp(arg, "-m") || !strcmp(arg, "--modified")) {
427
- show_modified = 1;
428
- require_work_tree = 1;
429
- continue;
430
- }
431
- if (!strcmp(arg, "-o") || !strcmp(arg, "--others")) {
432
- show_others = 1;
433
- require_work_tree = 1;
434
- continue;
435
- }
436
- if (!strcmp(arg, "-i") || !strcmp(arg, "--ignored")) {
437
- dir.flags |= DIR_SHOW_IGNORED;
438
- require_work_tree = 1;
439
- continue;
440
- }
441
- if (!strcmp(arg, "-s") || !strcmp(arg, "--stage")) {
442
- show_stage = 1;
443
- continue;
444
- }
445
- if (!strcmp(arg, "-k") || !strcmp(arg, "--killed")) {
446
- show_killed = 1;
447
- require_work_tree = 1;
448
- continue;
449
- }
450
- if (!strcmp(arg, "--directory")) {
451
- dir.flags |= DIR_SHOW_OTHER_DIRECTORIES;
452
- continue;
453
- }
454
- if (!strcmp(arg, "--no-empty-directory")) {
455
- dir.flags |= DIR_HIDE_EMPTY_DIRECTORIES;
456
- continue;
457
- }
458
- if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) {
459
- /* There's no point in showing unmerged unless
460
- * you also show the stage information.
461
- */
462
- show_stage = 1;
463
- show_unmerged = 1;
464
- continue;
465
- }
466
- if (!strcmp(arg, "-x") && i+1 < argc) {
467
- exc_given = 1;
468
- add_exclude(argv[++i], "", 0, &dir.exclude_list[EXC_CMDL]);
469
- continue;
470
- }
471
- if (!prefixcmp(arg, "--exclude=")) {
472
- exc_given = 1;
473
- add_exclude(arg+10, "", 0, &dir.exclude_list[EXC_CMDL]);
474
- continue;
475
- }
476
- if (!strcmp(arg, "-X") && i+1 < argc) {
477
- exc_given = 1;
478
- add_excludes_from_file(&dir, argv[++i]);
479
- continue;
480
- }
481
- if (!prefixcmp(arg, "--exclude-from=")) {
482
- exc_given = 1;
483
- add_excludes_from_file(&dir, arg+15);
484
- continue;
485
- }
486
- if (!prefixcmp(arg, "--exclude-per-directory=")) {
487
- exc_given = 1;
488
- dir.exclude_per_dir = arg + 24;
489
- continue;
490
- }
491
- if (!strcmp(arg, "--exclude-standard")) {
492
- exc_given = 1;
493
- setup_standard_excludes(&dir);
494
- continue;
495
- }
496
- if (!strcmp(arg, "--full-name")) {
497
- prefix_offset = 0;
498
- continue;
499
- }
500
- if (!strcmp(arg, "--error-unmatch")) {
501
- error_unmatch = 1;
502
- continue;
503
- }
504
- if (!prefixcmp(arg, "--with-tree=")) {
505
- with_tree = arg + 12;
506
- continue;
507
- }
508
- if (!prefixcmp(arg, "--abbrev=")) {
509
- abbrev = strtoul(arg+9, NULL, 10);
510
- if (abbrev && abbrev < MINIMUM_ABBREV)
511
- abbrev = MINIMUM_ABBREV;
512
- else if (abbrev > 40)
513
- abbrev = 40;
514
- continue;
515
- }
516
- if (!strcmp(arg, "--abbrev")) {
517
- abbrev = DEFAULT_ABBREV;
518
- continue;
519
- }
520
- if (*arg == '-')
521
- usage(ls_files_usage);
522
- break;
489
+ argc = parse_options(argc, argv, builtin_ls_files_options,
490
+ ls_files_usage, 0);
491
+ if (show_tag || show_valid_bit) {
492
+ tag_cached = "H ";
493
+ tag_unmerged = "M ";
494
+ tag_removed = "R ";
495
+ tag_modified = "C ";
496
+ tag_other = "? ";
497
+ tag_killed = "K ";
498
}
499
+ if (show_modified || show_others || (dir.flags & DIR_SHOW_IGNORED) || show_killed)
500
+ require_work_tree = 1;
501
+ if (show_unmerged)
502
+ /*
503
+ * There's no point in showing unmerged unless
504
+ * you also show the stage information.
505
+ */
506
+ show_stage = 1;
507
+ if (dir.exclude_per_dir)
508
+ exc_given = 1;
509
510
if (require_work_tree && !is_inside_work_tree())
511
setup_work_tree();
512
528
- pathspec = get_pathspec(prefix, argv + i);
513
+ pathspec = get_pathspec(prefix, argv);
514
515
/* be nice with submodule patsh ending in a slash */
516
read_cache();