commit c09a553dff65da50eb12a2ec1b10799f7dad0c73 from: Stefan Sperling date: Mon Mar 12 20:19:31 2018 UTC add a 'got checkout' command commit - 4847cca148b9969c7270f53e12008d8be7dd01a7 commit + c09a553dff65da50eb12a2ec1b10799f7dad0c73 blob - 1336114cb5e36a5ac7b41ce49c8492b9894258ca blob + 8e741204236a2eac2d5340b57fde5b4e4a7d1eb6 --- got/Makefile +++ got/Makefile @@ -1,8 +1,8 @@ .PATH:${.CURDIR}/../lib PROG= got -SRCS= got.c delta.c error.c object.c path.c pack.c refs.c \ - repository.c sha1.c zbuf.c +SRCS= got.c delta.c error.c fileindex.c object.c path.c pack.c \ + refs.c repository.c sha1.c worktree.c zbuf.c CPPFLAGS = -I${.CURDIR}/../include -I${.CURDIR}/../lib LDADD = -lutil -lz blob - ac347fdac94c53d1697fe1ab056f2c6bbae66026 blob + 8d6ac0cdfc8e63e43ed004d20ff75c4de905db79 --- got/got.c +++ got/got.c @@ -24,11 +24,13 @@ #include #include #include +#include #include "got_error.h" #include "got_object.h" #include "got_refs.h" #include "got_repository.h" +#include "got_worktree.h" #ifndef nitems #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) @@ -42,12 +44,16 @@ struct cmd { }; __dead void usage(void); +__dead void usage_checkout(void); __dead void usage_log(void); +const struct got_error* cmd_checkout(int, char *[]); const struct got_error* cmd_log(int, char *[]); const struct got_error* cmd_status(int, char *[]); struct cmd got_commands[] = { + { "checkout", cmd_checkout, usage_checkout, + "check out a work tree from a repository" }, { "log", cmd_log, usage_log, "show repository history" }, #ifdef notyet @@ -66,9 +72,6 @@ main(int argc, char *argv[]) setlocale(LC_ALL, ""); - if (pledge("stdio rpath wpath cpath", NULL) == -1) - err(1, "pledge"); - while ((ch = getopt(argc, argv, "h")) != -1) { switch (ch) { case 'h': @@ -124,6 +127,80 @@ usage(void) exit(1); } +__dead void +usage_checkout(void) +{ + fprintf(stderr, "usage: %s checkout REPO_PATH [WORKTREE_PATH]\n", + getprogname()); + exit(1); +} + +const struct got_error * +cmd_checkout(int argc, char *argv[]) +{ + const struct got_error *error = NULL; + struct got_repository *repo = NULL; + struct got_reference *head_ref = NULL; + struct got_worktree *worktree = NULL; + char *repo_path = NULL; + char *worktree_path = NULL; + + if (pledge("stdio rpath wpath cpath flock", NULL) == -1) + err(1, "pledge"); + + if (argc == 2) { + char *cwd, *base, *dotgit; + repo_path = argv[1]; + cwd = getcwd(NULL, 0); + if (cwd == NULL) + err(1, "getcwd"); + base = basename(repo_path); + if (base == NULL) + err(1, "basename"); + dotgit = strstr(base, ".git"); + if (dotgit) + *dotgit = '\0'; + if (asprintf(&worktree_path, "%s/%s", cwd, base) == -1) { + free(cwd); + return got_error(GOT_ERR_NO_MEM); + } + free(cwd); + } else if (argc == 3) { + repo_path = argv[1]; + worktree_path = strdup(argv[2]); + if (worktree_path == NULL) + return got_error(GOT_ERR_NO_MEM); + } else + usage_checkout(); + + printf("%s %s %s %s\n", getprogname(), argv[0], repo_path, worktree_path); + + error = got_repo_open(&repo, repo_path); + if (error != NULL) + goto done; + error = got_ref_open(&head_ref, repo, GOT_REF_HEAD); + if (error != NULL) + goto done; + + error = got_worktree_init(worktree_path, head_ref, "/", repo); + if (error != NULL) + goto done; + + error = got_worktree_open(&worktree, worktree_path); + if (error != NULL) + goto done; + + error = got_worktree_checkout_files(worktree, head_ref, repo); + if (error != NULL) + goto done; + + printf("checked out %s\n", worktree_path); + +done: + free(worktree_path); + return error; +} + static const struct got_error * print_commit_object(struct got_object *, struct got_object_id *, struct got_repository *);