commit 715dc77e943615d42425212556295bc0dbd35a6e from: Stefan Sperling date: Sat Aug 03 14:40:05 2019 UTC add 'got stage' command commit - 4200573374f974a69490f25c80a01c2e53968db9 commit + 715dc77e943615d42425212556295bc0dbd35a6e blob - e090e019f5dc2e375c14defab4fd0b6a79462cba blob + 5ce42cbb34750c1806b8be47db8426916ee452cd --- got/got.c +++ got/got.c @@ -95,6 +95,7 @@ __dead static void usage_cherrypick(void); __dead static void usage_backout(void); __dead static void usage_rebase(void); __dead static void usage_histedit(void); +__dead static void usage_stage(void); static const struct got_error* cmd_init(int, char *[]); static const struct got_error* cmd_import(int, char *[]); @@ -115,6 +116,7 @@ static const struct got_error* cmd_cherrypick(int, ch static const struct got_error* cmd_backout(int, char *[]); static const struct got_error* cmd_rebase(int, char *[]); static const struct got_error* cmd_histedit(int, char *[]); +static const struct got_error* cmd_stage(int, char *[]); static struct got_cmd got_commands[] = { { "init", cmd_init, usage_init, "" }, @@ -136,6 +138,7 @@ static struct got_cmd got_commands[] = { { "backout", cmd_backout, usage_backout, "bo" }, { "rebase", cmd_rebase, usage_rebase, "rb" }, { "histedit", cmd_histedit, usage_histedit, "he" }, + { "stage", cmd_stage, usage_stage, "sg" }, }; static void @@ -5146,7 +5149,112 @@ done: got_ref_close(tmp_branch); if (worktree) got_worktree_close(worktree); + if (repo) + got_repo_close(repo); + return error; +} + +__dead static void +usage_stage(void) +{ + fprintf(stderr, "usage: %s stage file-path ...\n", + getprogname()); + exit(1); +} + +static const struct got_error * +cmd_stage(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + struct got_repository *repo = NULL; + struct got_worktree *worktree = NULL; + char *cwd = NULL; + struct got_pathlist_head paths; + struct got_pathlist_entry *pe; + const char *worktree_path; + int ch, x; + + TAILQ_INIT(&paths); + + while ((ch = getopt(argc, argv, "")) != -1) { + switch (ch) { + default: + usage_stage(); + /* NOTREACHED */ + } + } + + argc -= optind; + argv += optind; + +#ifndef PROFILE + if (pledge("stdio rpath wpath cpath fattr flock proc exec sendfd " + "unveil", NULL) == -1) + err(1, "pledge"); +#endif + if (argc < 1) + usage_stage(); + + cwd = getcwd(NULL, 0); + if (cwd == NULL) { + error = got_error_from_errno("getcwd"); + goto done; + } + + error = got_worktree_open(&worktree, cwd); + if (error) + 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), 1, + got_worktree_get_root_path(worktree)); + if (error) + goto done; + + worktree_path = got_worktree_get_root_path(worktree); + for (x = 0; x < argc; x++) { + char *path = realpath(argv[x], NULL); + if (path == NULL) { + if (errno != ENOENT) { + error = got_error_from_errno2("realpath", + argv[x]); + goto done; + } + if (got_path_is_child(argv[x], worktree_path, + strlen(worktree_path))) { + path = strdup(argv[x]); + if (path == NULL) { + error = got_error_from_errno("strdup"); + goto done; + } + + } else if (asprintf(&path, "%s/%s", + got_worktree_get_root_path(worktree), + argv[x]) == -1) { + error = got_error_from_errno("asprintf"); + goto done; + } + } + + got_path_strip_trailing_slashes(path); + error = got_pathlist_insert(&pe, &paths, path, NULL); + if (error) { + free(path); + goto done; + } + } + error = got_worktree_stage(worktree, &paths, print_status, NULL, repo); +done: if (repo) got_repo_close(repo); + if (worktree) + got_worktree_close(worktree); + TAILQ_FOREACH(pe, &paths, entry) + free((char *)pe->path); + got_pathlist_free(&paths); + free(cwd); return error; }