commit 6bad629b50d093da48f6347e1dd806d56bf05a1e from: Stefan Sperling date: Mon Feb 04 14:05:36 2019 UTC add 'got status' command commit - f8d1f275c50bc69aed2c12b2efacf5923c9c4a4b commit + 6bad629b50d093da48f6347e1dd806d56bf05a1e blob - 1f262f0cc13c58a418ead0547d47fa568730d0be blob + 374ed5e84b7472ab124872d9e03621f6e9df94da --- got/got.1 +++ got/got.1 @@ -109,8 +109,19 @@ Update the work tree to the specified .Ar commit . The expected argument is a SHA1 hash which corresponds to a commit object. .El -.\".It Cm status -.\"Show current status of files. +.It Cm status [ Ar worktree-path ] +Show the current modification status of files in a worktree, +using the following status codes: +.Bl -column YXZ description +.It M Ta modified file +.It ! Ta versioned file was expected on disk but is missing +.It ? Ta unversioned item not tracked by +.Nm +.El +.Pp +If the +.Ar work tree path +is omitted, use the current working directory. .It Cm log [ Fl c Ar commit ] [ Fl C Ar number ] [ Fl f ] [ Fl l Ar N ] [ Fl p ] [ Fl r Ar repository-path ] [ path ] Display history of a repository. If a blob - bedd053bfd85bcf4daedb8cabb19a4ef5b948f82 blob + 21e4910f5bcd87ece0560e051f115d801f404a25 --- got/got.c +++ got/got.c @@ -75,6 +75,7 @@ __dead static void usage_log(void); __dead static void usage_diff(void); __dead static void usage_blame(void); __dead static void usage_tree(void); +__dead static void usage_status(void); static const struct got_error* cmd_checkout(int, char *[]); static const struct got_error* cmd_update(int, char *[]); @@ -82,9 +83,7 @@ static const struct got_error* cmd_log(int, char *[]) static const struct got_error* cmd_diff(int, char *[]); static const struct got_error* cmd_blame(int, char *[]); static const struct got_error* cmd_tree(int, char *[]); -#ifdef notyet static const struct got_error* cmd_status(int, char *[]); -#endif static struct cmd got_commands[] = { { "checkout", cmd_checkout, usage_checkout, @@ -99,10 +98,8 @@ static struct cmd got_commands[] = { " show when lines in a file were changed" }, { "tree", cmd_tree, usage_tree, " list files and directories in repository" }, -#ifdef notyet { "status", cmd_status, usage_status, "show modification status of files" }, -#endif }; int @@ -218,7 +215,7 @@ checkout_progress(void *arg, unsigned char status, con } static const struct got_error * -checkout_cancel(void *arg) +check_cancelled(void *arg) { if (sigint_received || sigpipe_received) return got_error(GOT_ERR_CANCELLED); @@ -410,7 +407,7 @@ cmd_checkout(int argc, char *argv[]) } error = got_worktree_checkout_files(worktree, repo, - checkout_progress, worktree_path, checkout_cancel, NULL); + checkout_progress, worktree_path, check_cancelled, NULL); if (error != NULL) goto done; @@ -535,7 +532,7 @@ cmd_update(int argc, char *argv[]) } error = got_worktree_checkout_files(worktree, repo, - update_progress, &did_something, checkout_cancel, NULL); + update_progress, &did_something, check_cancelled, NULL); if (error != NULL) goto done; @@ -1349,83 +1346,74 @@ done: return error; } -#ifdef notyet -static const struct got_error * -cmd_status(int argc __unused, char *argv[] __unused) -{ - git_repository *repo = NULL; - git_status_list *status; - git_status_options statusopts; - size_t i; +__dead static void +usage_status(void) +{ + fprintf(stderr, "usage: %s status [worktree-path]\n", getprogname()); + exit(1); +} - git_libgit2_init(); - - if (git_repository_open_ext(&repo, ".", 0, NULL)) - errx(1, "git_repository_open: %s", giterr_last()->message); - - if (git_repository_is_bare(repo)) - errx(1, "bar repository"); - - if (git_status_init_options(&statusopts, GIT_STATUS_OPTIONS_VERSION)) - errx(1, "git_status_init_options: %s", giterr_last()->message); +static void +print_status(void *arg, unsigned char status, const char *path) +{ + printf("%c %s\n", status, path); +} - statusopts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR; - statusopts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | - GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX | - GIT_STATUS_OPT_SORT_CASE_SENSITIVELY; +static const struct got_error * +cmd_status(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + struct got_repository *repo = NULL; + struct got_worktree *worktree = NULL; + char *worktree_path = NULL; + int ch; - if (git_status_list_new(&status, repo, &statusopts)) - errx(1, "git_status_list_new: %s", giterr_last()->message); - - for (i = 0; i < git_status_list_entrycount(status); i++) { - const git_status_entry *se; - - se = git_status_byindex(status, i); - switch (se->status) { - case GIT_STATUS_WT_NEW: - printf("? %s\n", se->index_to_workdir->new_file.path); - break; - case GIT_STATUS_WT_MODIFIED: - printf("M %s\n", se->index_to_workdir->new_file.path); - break; - case GIT_STATUS_WT_DELETED: - printf("R %s\n", se->index_to_workdir->new_file.path); - break; - case GIT_STATUS_WT_RENAMED: - printf("m %s -> %s\n", - se->index_to_workdir->old_file.path, - se->index_to_workdir->new_file.path); - break; - case GIT_STATUS_WT_TYPECHANGE: - printf("t %s\n", se->index_to_workdir->new_file.path); - break; - case GIT_STATUS_INDEX_NEW: - printf("A %s\n", se->head_to_index->new_file.path); - break; - case GIT_STATUS_INDEX_MODIFIED: - printf("M %s\n", se->head_to_index->old_file.path); - break; - case GIT_STATUS_INDEX_DELETED: - printf("R %s\n", se->head_to_index->old_file.path); - break; - case GIT_STATUS_INDEX_RENAMED: - printf("m %s -> %s\n", - se->head_to_index->old_file.path, - se->head_to_index->new_file.path); - break; - case GIT_STATUS_INDEX_TYPECHANGE: - printf("t %s\n", se->head_to_index->old_file.path); - break; - case GIT_STATUS_CURRENT: + while ((ch = getopt(argc, argv, "")) != -1) { + switch (ch) { default: - break; + usage(); + /* NOTREACHED */ } } - git_status_list_free(status); - git_repository_free(repo); - git_libgit2_shutdown(); + argc -= optind; + argv += optind; - return 0; -} +#ifndef PROFILE + if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil", + NULL) == -1) + err(1, "pledge"); #endif + if (argc == 0) { + worktree_path = getcwd(NULL, 0); + if (worktree_path == NULL) { + error = got_error_from_errno(); + goto done; + } + } else if (argc == 1) { + worktree_path = realpath(argv[0], NULL); + if (worktree_path == NULL) { + error = got_error_from_errno(); + goto done; + } + } else + usage_status(); + + error = got_worktree_open(&worktree, worktree_path); + if (error != NULL) + goto done; + + error = got_repo_open(&repo, got_worktree_get_repo_path(worktree)); + if (error != NULL) + goto done; + + error = apply_unveil(got_repo_get_path(repo), worktree_path); + if (error) + goto done; + + error = got_worktree_status(worktree, repo, print_status, NULL, + check_cancelled, NULL); +done: + free(worktree_path); + return error; +}